如何使用SimpleXML获得节点的属性与命名空间? [关闭] 如何使用SimpleXML获得节

2019-05-12 11:01发布

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 :(
}   

Answer 1:

你在你的问题已经得到了代码做的工作 。 你已经正确写入,你可以从一个命名空间的元素,是不是在默认的命名空间的根元素通过利用的访问属性SimpleXMLElement::children()方法与XML命名空间相关参数$ns$is_prefix

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

由于这基本上是因为你在你的问题也一样,可以说你已经回答了你自己的问题。 与扩展比较在线演示#2 。


龙答:你在你的问题已经得到了代码确实工作 。 你可以在网上找到你的示例XML和代码在交互式这里举例: 在线演示#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版本,例如得到一个致命的错误:

致命错误:调用未定义的方法的SimpleXMLElement ::使用getNamespaces()

也可能由于过时的libxml版本。 据测试,下面的libxml版本的做工精细用PHP 5.1.2-5.5.0:

  • ibxml版本:2.9.1
  • ibxml版本:2.8.0
  • ibxml版本:2.7.8


Answer 2:

所以,我发现了一个办法做到这一点使用XPath,这是最好的办法还是有这就是我的问题代码一致的方式吗? 只是出于好奇。

$source = 'youtube.xml';

// load as file
$youtube = new SimpleXMLElement($source, null, true);
$youtube->registerXPathNamespace('yt', 'http://gdata.youtube.com/schemas/2007');

$count = 0;
foreach($youtube->entry as $item){

    //title works
    echo $item->title;

    $attributes = $item->xpath('//yt:duration/@seconds');
    echo $attributes[$count]['seconds'];
    $count++;
}


Answer 3:

我这种情况做斗争,以及后来我找到了解决办法。 这是关于如何阅读复杂的XML属性名字空间那么简单。

foreach($media->group->content as $content) {
    $attrs = $content->attributes();
    $ytformat = $content->attributes("yt","format");

    echo(" attr = " . $ytformat . "; ");

    if ($ytformat == 5) {
        $url = $attrs['url'];
        $type = $attrs['type'];

        echo ($url . " - " . $type);
    }
}

希望能帮助到你...:)



Answer 4:

下面是使用属性()和子女()只,测试,工作正常另一种解决方案! :)

$data=<<<XML

<rss version="2.0" xmlns:media="http://search.yahoo.com/mrss/">
 <channel>
   <item>
    <title>Title: 0</title>
    <link test="test" test2="This is a test">Link:0</link>
    <media:thumbnail url="Thumbnail URL: 0"/>
    <media:content url="Content URL: 0" type="video/mp4" />
  </item>
    <item>
    <title>Title: 1</title>
    <link>Link:1</link>
    <media:thumbnail url="1"/>
    <media:content url="1" type="video/mp4" />
  </item>
 </channel>
</rss>

XML;



$xml=simplexml_load_string($data);

//reading simple node
echo $xml->channel[0]->item[0]->title;

echo "<br>----------------------------------<br>";

//reading/updating simple node's attribute
echo $xml->channel[0]->item[0]->link->attributes()->test2="This is a NEW test!.";

echo "<br>----------------------------------<br>";

//reading/updating namespaced node's attribute
echo $xml->channel[0]->item[0]->children('media',TRUE)->content->attributes()->type="VIDEO/MP6";

//saving...
$xml->asXml('updated.xml');


文章来源: How to get attribute of node with namespace using SimpleXML? [closed]