Jump to content

[SOLVED] Writing to XML using either DOM or SimpleXML


Recommended Posts

Hello everyone,

 

I've been having quite some trouble figuring out specific XML coding in PHP5. I'm trying to edit and remove specific tags in a specific way using DOM (I'd rather use SimpleXML but it seems rather limited on this area).

 

My FIRST problem

My first XML file looks like this:

<root>
<a>
    <aa>
        <aaa>John</aaa>
        <bbb>123456</bbb>
    </aa>
    <aa>
        <aaa>Paul</aaa>
        <bbb>654321</bbb>
    </aa>
</a>
<b>
    <aa>
        <aaa>John</aaa>
        <bbb>123456</bbb>
    </aa>
    <aa>
        <aaa>Paul</aaa>
        <bbb>654321</bbb>
    </aa>
</b>
</root>

 

I'm trying to remove "Paul" and "654321", and the <aa></aa> it is in from the <b></b> node. However, using my code it doesn't get any further than leaving the <aa> behind empty, changing the file to

 

<root>
...
<b>
    <aa>
        <aaa>John</aaa>
        <bbb>123456</bbb>
    </aa>
    <aa/>
</b>
...
</root>

 

I'm wondering how to make it not only delete the tags I want deleted (as it does now), but also the tag it leaves empty (<aa/>). My code is available if anyone would like to look into it, i'm leaving it out to avoid too much of a code flood in my very first forum post.

 

My SECOND problem

 

In a code with this layout:

<root>
<a>
    <aa>
        <aaa>Richard</aaa>
    </aa>
</a>
</root>

i'm "simply" trying to change "Richard" to "George". I've, however, not a clue how to do this. I seem to require ReplaceChild() somehow, but I'm clueless as to how exactly.

 

I hope someone can help me on either or both problems, it'd be greatly appreciated!

 

Thank you very much for reading my post,

spamgoat

Well, if you insist!

 

Here's the code i'm using for the first example:

 

  $doc = new DOMDocument();
  $doc->load('example.xml');
  $return1 = $doc->getElementsByTagName("b");
  foreach ($return1 as $return2) {
  	$return3 = $return2->getElementsByTagName("aa");
  	foreach ($return3 as $return4) {
  		$return5 = $return4->getElementsByTagName("aaa");
  		$return6 = $return5->item(0)->nodeValue;
	if ($return6 == "Paul") { 
		$hasfound = 1;
		$return5 = $return4->getElementsByTagName("aaa")->item(0);
		$oldr = $return4->removechild($return5);
		$return5 = $return4->getElementsByTagName("bbb")->item(0);
		$oldr = $return4->removechild($return5);
	}
  	}
  }

 

As mentioned, it does delete the things I want it to delete, but the parent node <aa> of the specific one I want delete stays behind as empty <aa/>, which I don't want.

I saw a nice tutorial a while back on writing XML using a custom class. It wasn't php's simpleXML or DOM, but it looked easier and the site owner was offering assistance to anyone that needed help. You might search around the internet for "php XML class" and see what you find.

I've never used the DOM functions in PHP, but I've used them quite a bit in Javascript.  Based on what I know there and what I got from the code you posted, this might delete an aa node given the aaa and bbb values:

 

<?php

  /**
   * Search for the aa element that has the specified values in 
   * aaa and bbb and delete it from the document
   * @param object the dom object
   * @param string the aaa node value
   * @param string the bbb node value
   */
  function delete_aa($dom, $aaa_val, $bbb_val){
    $aas = $dom->getElementsByTagName('aa');
    foreach($aas as $aa){
      // Get the aaa and the bbb of this node
      $aaa = $aa->getElementsByTagName('aaa')->item(0)->nodeValue;
      $bbb = $aa->getElementsByTagName('bbb')->item(0)->nodeValue;
      if($aaa === $aaa_val && $bbb === $bbb_val){
        // Match
        $aa->parentNode->removeChild($aa);
        // break; // Uncomment this line if you want to end the search here
      }
    }
  }
?>

 

(edit) I didn't perform any error checking in that code; I left that up to you.

Here it is with basic error handling:

<?php

  /**
   * Search for the aa element that has the specified values in 
   * aaa and bbb and delete it from the document
   * @param object the dom object
   * @param string the aaa node value
   * @param string the bbb node value
   */
  function delete_aa($dom, $aaa_val, $bbb_val){
    $aas = $dom->getElementsByTagName('aa');
    if(empty($aas)){
      return;
    }
    foreach($aas as $aa){
      try{
        // Get the aaa and the bbb of this node
        $aaa = $aa->getElementsByTagName('aaa')->item(0)->nodeValue;
        $bbb = $aa->getElementsByTagName('bbb')->item(0)->nodeValue;
        if($aaa === $aaa_val && $bbb === $bbb_val){
          // Match
          $aa->parentNode->removeChild($aa);
          // break; // Uncomment this line if you want to end the search here
        }
      }catch(Exception $e){
        continue;
      }
    }
  }
?>

Thanks a lot for taking your time writing that code for me! And congratulations on your 1600th post. However, your code seems to do the exact same as my code, as it deletes the tags but then keeps the parent node the tags were in alive (but empty, so it looks like <aa/>). Your code looks better than mine, though.  ;)

The first problem in this thread is solved now. I decided to increase a $i once every time in that loop so I know exactly where I am. It's a bit of a cheap work-around which I was hoping to avoid, but at least it works properly.

 

Thanks again to roopurt18 for taking his time.

 

ps: This thread should not be set to "SOLVED" just yet, as there's one problem left. :)

pps: I figured out my second problem as well. Closing thread.

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.