2

How to get all the unique node names in XMLReader? Let's say for example I have below XML data:

<a>
    <b>
        <firstname>John</firstname>
        <lastname>Doe</lastname>
    </b>
    <c>
        <firstname>John</firstname>
        <lastname>Smith</lastname>
        <street>Streetvalue</street>
        <city>NYC</city>
    </c>
    <d>
        <street>Streetvalue</street>
        <city>NYC</city>
        <region>NY</region>
    </d>
</a>

How can I get firstname, lastname, street, city, region from above XML data using XMLReader? Also the file is very big, so need to see performance also while getting the node names.

Thanks

MagExt
  • 222
  • 3
  • 16

2 Answers2

3

I didn't get the chance to test it, but give this a try:

$reader = new XMLReader();
$reader->open($input_file);
$nodeList = array();

while ($reader->read())
{

    // We need to check if we're dealing with an Element
    if ($reader->nodeType == XMLReader::ELEMENT && $reader->name == 'b')
    {
        // Let's inspect the node's content as well
        while ($reader->read())
        {
            if ($reader->nodeType == XMLReader::ELEMENT)
            {
                 // Saving the node to an auxiliar array
                 array_push($nodeList, $reader->localName);
            }
        }
}

// Finally, let's filter the array
$nodeList = array_unique($nodeList);

Performance-wise, if the file is huge then XMLReader is the way to go since it only loads the current tag to memory (while DOMDocument, on the other hand, would load everything). Here's a more detailed explanation regarding the three techniques you can use to read the XML.

By the way, if the array containing the nodes grows too large run array_unique more periodically (instead of just doing it in the end), in order to trim it.

Community
  • 1
  • 1
João Pereira
  • 3,545
  • 7
  • 44
  • 53
  • Great, thanks! Do you know how to get the node names which only come under some particular node? Example only under ``, but `` have multiple occurrences. – MagExt Jul 10 '13 at 16:07
  • No it will only print `b`.. expected output is `firstname`,`lastname`. All the node names under a particular node. – MagExt Jul 10 '13 at 16:20
  • Re-editted. What about now? In any case, that's the theory, another loop inside the node you want – João Pereira Jul 10 '13 at 16:27
1

You can use simplexml_load_file function to load xml data in PHP object. Example using simplexml_load_string function

$xml_string = '<?xml version="1.0" encoding="UTF-8"?>
<a>
    <b>
        <firstname>John</firstname>
        <lastname>Doe</lastname>
    </b>
    <c>
        <firstname>John</firstname>
        <lastname>Smith</lastname>
        <street>Streetvalue</street>
        <city>NYC</city>
    </c>
    <d>
        <street>Streetvalue</street>
        <city>NYC</city>
        <region>NY</region>
    </d>
</a>';

$xml = simplexml_load_string($xml_string);
/* $xml = simplexml_load_file($file_name); */ // Use this to load xml data from file

// Data will be in $xml and you can iterate it like this
foreach ($xml as $x) {
    if (isset($x->firstname)) {
        echo $x->firstname . '<br>'; // $x->lastname, $x->street, $x->city also can be access this way
    }
}
Manoj Yadav
  • 6,560
  • 1
  • 23
  • 21