Searching and Replacing Nodes with SimpleXML in PHP 5

Want to learn how to get the most out of the “simpleXML” extension that comes bundled with PHP 5? Welcome to the last part of the series “Working with simpleXML in PHP 5.” In three tutorials, this series covers topics ranging from the basics of parsing XML files with this library, to performing advanced tasks, such as searching, extracting and replacing nodes, and interoperating with the XML DOM.

Introduction

Quite possibly, if you’ve read the two preceding articles of this series, you’ll know how to load XML files and strings onto PHP objects by using the helpful “simplexml_load_file()” and “simplexml_load_string()” functions. You’ll also know how to access parent and child XML nodes through a simple array syntax.

Also, at this point you’ll realize that one of the best things about this extension is how easily you can use it for parsing XML data by using typical foreach loops, which makes all the XML processing operations a breeze. Here, there’s no need to deal with complex parsers. Once XML data has been stored in a PHP object, the process for accessing nodes is reduced to navigating the corresponding tree and calling the appropriate methods.

So far, the couple of functions that I mentioned before actually do a good job of  parsing simple XML files and strings. However, the “simpleXML” library has a few additional handy functions that I’d like to show you in this last tutorial. That said, in the next few lines, I’ll be covering these functions, in order to demonstrate how to quickly search and replace nodes within XML data strings.

So that’s the subject of this article. It’s time to continue learning about the “simpleXML” extension. Let’s do it together!

{mospagebreak title=Going deeper into parsing XML strings: comparing nodes}

To demonstrate how nodes of a given XML string can be compared, first I’ll create a PHP file that will contain the string in question. Here’s the source code for this file:

$xmlstr=<<<XML
<?xml version=”1.0″ encoding=”iso-8859-1″?>
<users>
<user>
<name>John Doe</name>
<address>Binary Avenue 1234 FL</address>
<email>john@john-domain.com</email>
<gender type=”male”>1</gender>
<gender type=”female”>2</gender>
</user>
<user>
<name>Janet Smith</name>
<address>Crazy Bits Road 4568 CA</address>
<email>janet@janet-domain.com</email>
<gender type=”male”>1</gender>
<gender type=”female”>2</gender>
</user>
<user>
<name>James Smith</name>
<address>Socket Boulevard 7894 OH</address>
<email>james@james-domain.com</email>
<gender type=”male”>1</gender>
<gender type=”female”>2</gender>
</user>
<user>
<name>Silvia Wilson</name>
<address>Protocol Avenue 5652 NY</address>
<email>silvia@silvia-domain.com</email>
<gender type=”male”>1</gender>
<gender type=”female”>2</gender>
</user>
<user>
<name>Alejandro Gervasio</name>
<address>Boulevard of Objects 10101 AR</address>
<email>alejandro@alejandro-domain.com</email>
<gender type=”male”>1</gender>
<gender type=”female”>2</gender>
</user>
</users>
XML;

All right, now that I have an XML string to work with, take a look at the example below, which first loads the XML data onto an object and next compares a specific node with a predefined value:

require_once ‘xml_string.php';
if(!$xml=simplexml_load_string($xmlstr)){
    trigger_error(‘Error reading XML string’,E_USER_ERROR);
}
$message=(string)$xml->user[4]->name==’Alejandro Gervasio’?’User
found!':’User not found!';
echo $message;

With this example, you can learn how XML nodes can be compared and evaluated appropriately. Notice that prior to performing the comparison, string type casting is applied to the selected node, because nodes are accessed originally as objects.

With reference to the previous example, its output is the following:

User found!

Since the example you saw before is really simple, here’s another one, which also illustrates how to compare a different node of the same XML string:

require_once ‘xml_string1.php';
if(!$xml=simplexml_load_string($xmlstr)){
    trigger_error(‘Error reading XML string’,E_USER_ERROR);
}
$message=(string)$xml->user[4]->name==’Unexistent user’?’User not
found!':’User found!';
echo $message;

In this case, after executing the above script, this is the result that I get on my browser:

User not found!

As you can see, comparing nodes that belong to a given XML string is a straightforward process that doesn’t bear much discussion here. Therefore, let’s move on and learn how to locate specific XML nodes using another interesting function included with the “simpleXML” extension. I’m talking about the “Xpath()” method, which will be explained in the next few lines. Please keep on reading.

{mospagebreak title=Finding nodes inside a XML string: using the “Xpath()” method}

With regard to the localization of specific nodes within an XML string, the “simpleXML” extension comes with the handy “Xpath()” method, which allows you to locate particular nodes and iterate over them by utilizing a “foreach” loop. The following example demonstrates how to achieve this, so take a look at its source code:

// search <name> nodes
require_once ‘xml_string.php';
if(!$xml=simplexml_load_string($xmlstr)){
    trigger_error(‘Error reading XML string’,E_USER_ERROR);
}
foreach($xml->xpath(‘//name’) as $names){
    echo ‘Name node found with a value of ‘.$names.'<br />';
}

The script listed above uses the “Xpath()” method to find all the <name> nodes contained within the previous sample XML string. Notice the remarkable flexibility provided by this method, when searching nodes that match a given name. Simple and powerful, right?

And, of course, here is the corresponding output of the prior code snippet:

Name node found with a value of John Doe
Name node found with a value of Janet Smith
Name node found with a value of James Smith
Name node found with a value of Silvia Wilson
Name node found with a value of Alejandro Gervasio

In case the above example isn’t clear enough to you, here’s an additional one, which searches for and displays all the <email> nodes included within the respective sample XML data string:

// search <email> nodes
require_once ‘xml_string.php';
if(!$xml=simplexml_load_string($xmlstr)){
    trigger_error(‘Error reading XML string’,E_USER_ERROR);
}
foreach($xml->xpath(‘//email’) as $email){
    echo ‘Email node found with a value of ‘.$email.'<br />';
}

As you may have guessed, all the <email> nodes are properly located and displayed as follows:

Email node found with a value of john@john-domain.com
Email node found with a value of janet@janet-domain.com
Email node found with a value of james@james-domain.com
Email node found with a value of silvia@silvia-domain.com
Email node found with a value of alejandro@alejandro-domain.com

At this stage, hopefully you have learned how to search specific nodes within a given XML string by using the handy “Xpath()” method. Now, it’s time to see how these nodes can be replaced appropriately. Therefore, go ahead and read the next section.

{mospagebreak title=Replacing nodes within a XML string: using the “asXML()” method}

Fortunately, the “simpleXML” extension isn’t limited to finding specific nodes within a given XML string or file. You can replace particular XML elements by using the cool “asXML()” method with ease. But first of all, let me show you how this method can be utilized for replacing nodes on the fly.

Using the same XML string that you saw in the previous sections, here is how this method is used for substituting a particular element:

// setting new values for specific nodes with the asXML() method
require_once ‘xml_string.php';
if(!$xml=simplexml_load_string($xmlstr)){
    trigger_error(‘Error reading XML string’,E_USER_ERROR);
}
$xml->user[0]->name=’Jack Norton';
echo $xml->asXML();

If you examine the above script, you’ll possibly find it quite interesting. Please notice how the first user’s name is replaced with a different one by using the “asXML()” method. In this case, the logic of the script is very simple: first, the XML string is loaded onto an object, then the node being replaced is located by using the corresponding array syntax, and finally the “asXML()” method is invoked.

In fact, this method returns a new XML string, where the value of the selected node has been replaced with the new one, as shown below:

Jack Norton
Binary Avenue 1234 FL
John@domain.com 1 2 Janet Smith
Crazy Bits Road 4568 CA
Janet@janet-domain.com 1 2 James Smith
Socket Boulevard 7894 OH
James@james-domain.com 1 2 Silvia Wilson
Protocol Avenue 5652 NY
Silvia@silvia-domain.com 1 2 Alejandro Gervasio
Boulevard of Objects 10101 AR
Alejandro@alejandro-domain.com 1 2

As you’ll certainly agree, the behavior of this method is very convenient, since it only generates a new XML string on the fly, and leaves the original XML data untouched. Based on this example, try replacing other nodes and watch the different results that you’ll get in each case.

All right, now you know how to search and replace the nodes of a XML string, which is good and simple. So, what’s next? In the next section, I’ll be showing you how to use some additional methods of the “simpleXML” extension, in order to locate child nodes, access attributes and work with the XML DOM.

{mospagebreak title=Using a few additional methods: finding child nodes, accessing attributes and using the XML DOM}

As I said in the previous section, the “simpleXML” extension comes with some additional methods for parsing XML data, which can be quite useful, depending on the requirements of your PHP 5 applications.

The first method that I’ll explain is called “children()”, and as its name suggests, is aimed at finding all the child nodes of a parent element. To clarify how it can be used, I’ll use the following XML data string:

$xmlstr=<<<XML
<?xml version=”1.0″ encoding=”iso-8859-1″?>
<users>
<user>
<name>John Doe</name>
<address>Binary Avenue 1234 FL</address>
<email>john@domain.com</email>
<gender>
<type>Male</type>
</gender>
</user>
<user>
<name>Janet Smith</name>
<address>Crazy Bits Road 4568 CA</address>
<email>janet@janet-domain.com</email>
<gender>
<type>Female</type>
</gender>
</user>
</users>
XML;

As you can see, I created a new string of XML data, so you can have an accurate idea of how to access the child nodes of all the <gender> nodes. Now, take a look at the following script, which uses the “children()” method for performing this task:

// example finding child nodes of <gender> nodes with the
children() method
require_once ‘xml_string.php';
if(!$xml=simplexml_load_string($xmlstr)){
    trigger_error(‘Error reading XML string’,E_USER_ERROR);
}
foreach($xml->children() as $children){
    echo ‘Name node found with the following value: ‘.$children-
>name.'<br />';
    foreach($children->children() as $newchildren){
        if($newchildren->type!=”){
            echo ‘Gender node has the following child node:
‘.$newchildren->type.'<br />';
        }
    }
}

On this occasion, the above script utilizes the “children()” method inside two “foreach” loops, in order to find all the child nodes that belong to the corresponding <gender> elements, which outputs the following result:

Name node found with the following value: John Doe
Gender node has the following child node: Male
Name node found with the following value: Janet Smith
Gender node has the following child node: Female

Well, if the previous example is a little bit harder to understand, check out this one, which uses the following XML string and certainly is much simpler to read and code:

$xmlstr=<<<XML
<?xml version=”1.0″ encoding=”iso-8859-1″?>
<users>
<user>
<name>John Doe</name>
<address>Binary Avenue 1234 FL</address>
<email>john@john-domain.com</email>
<gender type=”male”>1</gender>
<gender type=”female”>2</gender>
</user>
<user>
<name>Janet Smith</name>
<address>Crazy Bits Road 4568 CA</address>
<email>janet@janet-domain.com</email>
<gender type=”male”>1</gender>
<gender type=”female”>2</gender>
</user>
<user>
<name>James Smith</name>
<address>Socket Boulevard 7894 OH</address>
<email>james@james-domain.com</email>
<gender type=”male”>1</gender>
<gender type=”female”>2</gender>
</user>
<user>
<name>Silvia Wilson</name>
<address>Protocol Avenue 5652 NY</address>
<email>silvia@silvia-domain.com</email>
<gender type=”male”>1</gender>
<gender type=”female”>2</gender>
</user>
<user>
<name>Alejandro Gervasio</name>
<address>Boulevard of Objects 10101 AR</address>
<email>alejandro@alejandro-domain.com</email>
<gender type=”male”>1</gender>
<gender type=”female”>2</gender>
</user>
</users>
XML;

require_once ‘xml_string.php';
if(!$xml=simplexml_load_string($xmlstr)){
    trigger_error(‘Error reading XML string’,E_USER_ERROR);
}
foreach($xml->children() as $children){
    echo ‘Name node with the following value ‘.$children->name.'<br />';
}

// displays the following output

Name node with the following value John Doe
Name node with the following value Janet Smith
Name node with the following value James Smith
Name node with the following value Silvia Wilson
Name node with the following value Alejandro Gervasio

Actually, the example shown above is rather trivial, but I just want you to grasp correctly the logic behind the “children()” method. Did you get it? I hope so.

Finally, the two methods that I’d like to show you are called “attributes()” and “simple_import_dom()” respectively. Obviously, the first one is focused on retrieving all the attributes that correspond to a specific XML node, while the second one is useful for importing a new DOM document as XML data.

With reference to the “attributes()” method, here is an example that teaches you how it can be implemented:

$xmlstr=<<<XML
<?xml version=”1.0″ encoding=”iso-8859-1″?>
<users>
<user name=”John Doe” address=”Binary Avenue 1234 FL” email=”john@john-domain.com”>User1</user>
<user name=”Janet Smith” address=”Crazy Bits Road 4568 CA” email=”janet@janet-domain.com”>User2</user>
</users>
XML;

// example using the ‘attributes()’ method
require_once ‘xml_string.php';
if(!$xml=simplexml_load_string($xmlstr)){
    trigger_error(‘Error reading XML string’,E_USER_ERROR);
}
foreach($xml->user[0]->attributes() as $attr=>$value){
    echo ‘Attribute ‘.$attr. ‘ found with the following value: ‘.$value.'<br />';
}

// displays the following output

Attribute name found with the following value: John Doe
Attribute address found with the following value: Binary Avenue
1234 FL
Attribute email found with the following value: john@john-
domain.com

As you can see, the “attributes()” method allows you to obtain all the attributes of a particular element within a XML string, which are returned as an associative array. In this case, I used basic XML data, so that you can easily understand how this method works.

After demonstrating how the “attributes()” method does its thing, take a little break and examine the code snippet below, which shows how to implement the “simplexml_import_dom()” method:

// example using the ‘import_dom()’ method
$dom=new domDocument;
if(!$dom->loadXML(‘<users><user><name>John
Doe</name><address>Binary Avenue 1234
FL</address><email>ohn@john-domain.com</email></user></users>’)){
    trigger_error(‘Error loading XML string’,E_USER_ERROR);
}
$xml=simplexml_import_dom($dom);
echo ‘Name of first user: ‘.$xml->user[0]->name;

// displays the following output

Name of first user: John Doe

I purposely kept the above example rather simple, since the XML DOM is a huge topic, and certainly is out of the scope of this series. In short, the “simplexml_import_dom()” method can be used as an alternative way to load XML data strings onto an object. It lets you obtain results similar to using both the “simplexml_load_file()” and “simplexml_load_string()” methods. However, if you want to take the shortest path to parsing XML data, I suggest you to use these methods instead.

Wrapping up

Finally, we’re done. Over the course of this series, I introduced some of the most important functions that are included within the “simpleXML” PHP 5 extension. As you saw, this library eventually might fit the requirements of many applications that don’t demand complex parsing of XML data. If your next PHP-driven project falls under this category, go ahead and use it with no restrictions. See you in the next PHP tutorial!

[gp-comments width="770" linklove="off" ]

antalya escort bayan antalya escort bayan Antalya escort diyarbakir escort