0

I have code something like this :

<?xml version="1.0" encoding="UTF-8"?>
<Personlist xmlns="http://example.org">
    <Person>
        <Name>Louis</Name>
        <Address>
            <StreetAddress>Somestreet</StreetAddress>
            <PostalCode>00001</PostalCode>
            <CountryName>Finland</CountryName>
        </Address>
    </Person>
    <Person>
        <Name>Rakshith</Name>
        <Address>
            <StreetAddress>Somestreet</StreetAddress>
            <PostalCode>00001</PostalCode>
            <CountryName>Finland</CountryName>
        </Address>
    </Person>
    <Person>
        <Name>Steve</Name>
        <Address>
            <StreetAddress>Someotherstreet</StreetAddress>
            <PostalCode>43400</PostalCode>
            <CountryName>Sweden</CountryName>
        </Address>
     </Person>
 </Personlist>

How to to stop looping if name 'Rakshith' found in xml dom parsing. And in simple xml parser we can directly access the nth element like $xml->Person[0]->Name. But in XML dom, we need to parse in foreach itself so far i know. Is there any way like this that would suit my requirement.

Thanks in advance

  • I think you need a sax parser for that... – eric.itzhak Mar 04 '14 at 10:34
  • Thanks for the fast reply @eric.itzhak. Previously i was using simple_xml_parser(). Because of undefined objects as suggested from one of the experts in this forum, i switched to xml dom. Now you are suggesting me for sax parser, now i am bit confused with these stuffs, which one should i opt. I am a little newbie to XML. Can you please assist me with this because in the XML webservices we are depending on will always be missing some tags from one to another details that leads to undefined object kind and stops execution. Which is the best XML parser to handle this according to you? Thanks –  Mar 04 '14 at 10:41
  • I'm no expert myself, but as far as I know, you can't stop dom parsers with your condition, that's why sax parsers is for... the thing is both `simple_xml_parser` and the one you apperently switched to are dom parsers, where the entire XML is built in memory prior to use, while the conept of sax parsers is that it's event based, where you don't actually build it in memory but iterate through it, don't know which one's better to use for you, but read about the differenes: http://stackoverflow.com/questions/6828703/what-is-the-difference-between-sax-and-dom – eric.itzhak Mar 04 '14 at 11:03

1 Answers1

0

If you're are using DOM. You can use Xpath to select just the nodes you want to iterate:

$dom = new DOMDocument();
$dom->loadXml($xml);
$xpath = new DOMXpath($dom);
$xpath->registerNamespace('ns1', 'http://example.org');

$persons = $xpath->evaluate('/ns1:Personlist/ns1:Person[ns1:Name = "Rakshith"]');
foreach ($persons as $person) {
  var_dump(
    $xpath->evaluate('string(ns1:Name)', $person),
    $xpath->evaluate('string(ns1:Address/ns1:CountryName)', $person)
  );
}

Output: https://eval.in/110336

string(8) "Rakshith"
string(7) "Finland"

Xpath is quite powerful. You're using expression with conditions to describe a list of nodes (that can be a list with a single node or an empty list, too). If you do something that implies a scalar value the first node in the list is used.

I you example, you define a default XML namespace. Here ist no default XML namespace in xpath, you register your own prefix and use it. The example uses "ns1".

The Xpath expression selects the Personlist document element

/ns1:Personlist

then its Person child elements:

/ns1:Personlist/ns1:Person

limits that list to nodes with a child Name with the the value "Rakshith"

/ns1:Personlist/ns1:Person[ns1:Name = "Rakshith"]

This will always return a list (an empty one if nothing is found) so it it possible to iterate that list without further validation.

Inside the loop expression are used with a context, provided as the second argument to evaluate. The string() function casts the result list into a string value.

ThW
  • 19,120
  • 3
  • 22
  • 44