Jump to content

SimpleXML and child elements


jfk888

Recommended Posts

I'm trying to parse an xml-file which is full of namespaces, here is an example:

 

<parent>
    <name>Bill Clinton jr.</name>
    <pr:element>
        <pr:code>123</pr:code>
        <pr:text>Hello!</pr:text>
    </pr:element>
    <cmn:address>
        <cmn:street>My Street 10</cmn:street>
        <cmn:zip>22334</cmn:zip>
    </cmn:address>
</parent>

 

I get the values like this:

 

$xml = simplexml_load_string($str);

$name = $xml->parent->name;
$code = $xml->parent->children('pr', true)->element->code;
$street = $xml->parent->children('cmn', true)->address->street;

 

But the fun part is that sometimes some of the elements may not exist, in this case it's the <cmn:address> element:

 

<parent>
    <name>Bill Clinton jr.</name>
    <pr:element>
        <pr:code>123</pr:code>
        <pr:text>Hello!</pr:text>
    </pr:element>
</parent>

$street = $xml->parent->children('cmn', true)->address->street;

 

The above code gives "Fatal error: Call to a member function children() on a non-object in...".

To avoid the fatal error I could check that the <cmn:address> exists, but the actual file can be nested very deep and there are many optional elements.

Checking every single element would cause me a hairloss.

 

In my dreams the above code example would just ignore the missing <cmn:address> element and the $street variable would stay empty.

 

I can't even suppress the fatal error (I do understand why) with the '@'-practice, well I can but the execution of the script stops as expected.

 

Is there any other ways to handle this situation?

Link to comment
https://forums.phpfreaks.com/topic/242844-simplexml-and-child-elements/
Share on other sites

<parent>
    <name>Bill Clinton jr.</name>
    <pr:element>
        <pr:code>123</pr:code>
        <pr:text>Hello!</pr:text>
    </pr:element>
</parent>

$street = $xml->parent->children('cmn', true)->address->street;

 

Your line of code is incorrect given the XML shown.  $xml will be the <parent> element so to try and access the <street> you would want:

 

$street = $xml->children('cmn', true)->address->street;

If the <cmn:address> is not present, the above will assign NULL to $street with no warnings or errors.

I try to be more specific.

 

$str = "
<xml xmlns:pr=\"http://www.example.com\">
    <element1>
        <element1>1</element1>
        <element2>2</element2>
    </element1>
    <element2>
        <element1>
            <pr:element1>1</pr:element1>
            <pr:element2>2</pr:element2>
        </element1>
        <element2>
            <pr:element1>1</pr:element1>
            <pr:element2>2</pr:element2>
        </element2>
        <!--
        <element3>
            <element1>
                <pr:element1>1</pr:element1>
                <pr:element2>2</pr:element2>
            </element1>
        </element3>
        -->
    </element2>
</xml>";

$xml = simplexml_load_string($str);

echo $xml->element1->element1 . '<br>';
echo $xml->element2->element1->children('pr', true)->element1 . '<br>';
echo $xml->element2->element2->children('pr', true)->element2 . '<br>';
echo $xml->element2->element3->children('pr', true)->element1 . '<br>';
echo $xml->element2->element3->element1->children('pr', true)->element1;

 

Result:

 

1
1
2
Warning: main(): Node no longer exists in /var/www/test.php on line 40 Call Stack: 0.0002 654960 1. {main}() /var/www/test.php:0
Fatal error: Call to a member function children() on a non-object in /var/www/test.php on line 41 Call Stack: 0.0002 654960 1. {main}() /var/www/test.php:0

 

When examining the xml, it seems that on the first non-existent level PHP gives a warning and one level further it gives a fatal error. My actual point was that if I can't be sure that a particular element exists in the xml-data, it seems that I can't use the above approach. If someone knows better, please tell me.

Archived

This topic is now archived and is closed to further replies.

×
×
  • 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.