简体   繁体   中英

PHP : how to parse XML with nested xpath elements

Here is the XML that I am working on :

<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:noo="http://www.myscheme.com/schema">
    <channel>
        <item>
            <title>A Simple Title</title>
            <noo:subcategory>the sub category</noo:subcategory>
            <noo:relatedInfos>
                <noo:teams>
                    <noo:team id="3">New York</noo:team>
                    <noo:team id="4">Las Vegas</noo:team>
                </noo:teams>
            </noo:relatedInfos>
        </item>
    </channel>
</rss>

I am doing this php code to get the two "team" but it does not work ($xml has the previous content) :

$xml_datas = simplexml_load_string($xml);

foreach($xml_datas->channel->item as $item){                      
    $noo = $item->children('noo');
    echo $noo->team;
}

Do you have any idea why it is not working ?

Thanks

See if this helps:

<?php // RAY_temp_userco.php
error_reporting(E_ALL);

$xml = <<<ENDXML
<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:noo="http://www.myscheme.com/schema">
    <channel>
        <item>
            <title>A Simple Title</title>
            <noo:subcategory>the sub category</noo:subcategory>
            <noo:relatedInfos>
                <noo:teams>
                    <noo:team id="3">New York</noo:team>
                    <noo:team id="4">Las Vegas</noo:team>
                </noo:teams>
            </noo:relatedInfos>
        </item>
    </channel>
</rss>
ENDXML;

$obj = simplexml_load_string($xml);

$ns = $obj->getNamespaces(TRUE);

foreach($obj->channel->item as $item){
    $noo = $item->children($ns['noo']);
    var_dump($noo);
}

"noo" is just a local alias for that namespace, and the ->children() method (and most XML handling functions) want to know its actual global identifier, which is the URI in the xmlns attribute.

You need to either specify the full identifier of the namespace (ie ->children('http://www.myscheme.com/schema') ) or set the optional second parameter to tell SimpleXML to look up the prefix ( ->children('noo', true) . The second may be more readable, but it will break if a future document has the same schema, but gives the namespace a different local alias.

Additionally, the team nodes aren't directly under the item node, so you need to traverse further to get them:

// Give the namespace a readable name that won't change
define('NS_NOO', 'http://www.myscheme.com/schema');

$xml_datas = simplexml_load_string($xml);

foreach($xml_datas->channel->item as $item){                      
    $teams = $item->children(NS_NOO)->relatedInfo->teams;
    echo $teams->team[0];
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM