php – 如何使用SimpleXML获取带有命名空间的节点的属性?

youtube.xml

<Feed xmlns="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mRSS/" xmlns:openSearch="http://a9.com/-/spec/opensearchRSS/1.0/" xmlns:gd="http://schemas.google.com/g/2005" xmlns:yt="http://gdata.youtube.com/schemas/2007">  

    <entry>
        ...
        <yt:duration seconds="1870"/>
        ...
    </entry>

</Feed>

update_videos.PHP

$source = 'youtube.xml';

// load as file
$youtube = new SimpleXMLElement($source, null, true);

foreach($youtube->entry as $item){
    //title works
    echo $item->title;

    //Now how to get seconds? My attempt...
    $namespaces = $item->getNameSpaces(true);
    $yt = $item->children($namespaces['yt']);
    $seconds = $yt->duration->attributes();
    echo $seconds['seconds'];
    //but doesn't work :(
}   

解决方法:

你在问题中得到的代码确实有效.您已经正确地编写了可以通过使用带有XML命名空间相关参数$ns和$is_prefix的SimpleXMLElement::children() method来从不在认命名空间中的namespaced-element访问属性作为根元素:

$youtube->entry->children('yt', TRUE)->duration->attributes()->seconds; // is "1870"

由于这与您在问题中的基本相同,可以说您已经回答了自己的问题.与扩展的Online Demo #2相比.

答案很长:你在问题中得到的代码确实有效.您可以在此处在线交互式示例中找到示例XML和代码Online Demo #1 – 它显示了具有不同PHP和LIBXML版本的结果.

码:

$buffer = '<Feed xmlns="http://www.w3.org/2005/Atom" xmlns:yt="http://gdata.youtube.com/schemas/2007">
    <entry>
        <yt:duration seconds="1870"/>
    </entry>
</Feed>';

$xml = new SimpleXMLElement($buffer);

echo "ibxml version: ", LIBXML_DottED_VERSION, "\n";

foreach ($xml->entry as $item)
{
    //original comment: how to get seconds?
    $namespaces = $item->getNameSpaces(true);
    $yt         = $item->children($namespaces['yt']);
    $seconds    = $yt->duration->attributes();

    echo $seconds['seconds'], "\n"; // original comment: but doesn't work.
}

echo "done. should read 1870 one time.\n";

结果:

输出为5.3.26,5.4.16 – 5.5.0

ibxml version: 2.9.1
1870
done. should read 1870 one time.

输出为5.3.15 – 5.3.24,5.4.5 – 5.4.15

ibxml version: 2.8.0
1870
done. should read 1870 one time.

输出为5.1.2 – 5.3.14,5.4.0 – 5.4.4

ibxml version: 2.7.8
1870
done. should read 1870 one time.

从这个角度看,一切都很好.由于您没有给出任何具体的错误描述,因此很难说您的案例出了什么问题.您可能正在使用在您提出问题时过时的PHP版本,例如收到致命错误

Fatal error: Call to undefined method SimpleXMLElement::getNameSpaces()

可能也是由于过时的libxml版本.根据测试,以下libxml版本适用于PHP 5.1.2-5.5.0:

> ibxml版本:2.9.1
> ibxml版本:2.8.0
> ibxml版本:2.7.8

相关文章

统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...
统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...
前言 之前做了微信登录,所以总结一下微信授权登录并获取用户...
FastAdmin是我第一个接触的后台管理系统框架。FastAdmin是一...
之前公司需要一个内部的通讯软件,就叫我做一个。通讯软件嘛...
统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...