2017-02-02 33 views
0

鉴于XML和相关的PHP,下面如何以与获得非名称空间值相同的方式获得名称空间值?我一直在谈论关于此的其他一些SE QA,但似乎无法做到。感谢您的帮助。 :)如何从名称空间和非名称空间XML的混合中获取值

<?xml version="1.0" encoding="UTF-8"?> 
<rss version="2.0" xmlns:psg="http://b3000.example.net:3000/psg_namespace/"> 
    <channel> 
    <title>Example</title> 
    <description>example stuff</description> 
    <item> 
     <psg:eventId>406589</psg:eventId> 
     <psg:duration>3482</psg:duration> 
    </item> 
    </channel> 
</rss> 

$xml = new SimpleXMLElement($source, null, true); 
foreach($xml->channel->item as $entry){ 
    echo $entry->title;   // This works 
    echo $entry->description; // This works 
    echo $entry->item->duration // Pseudo of what I need 
} 

如何获得持续时间?我与变化的尝试,如这已经失败

$namespaces = $item->getNameSpaces(true); 
$psg = $item->children($namespaces['psg']); 

更新

虽然这不是我实际上是寻找答案,我必须接受这让我想的东西,导致第一个答案实际的问题 - “操作员错误”!这样做的工作....我的问题是在试图找出它,我正在调试echo print_r($psg, true)。这显示了SimpleXmlObject的结果,然后让我追逐如何获得这些属性 - 我所要做的就是分配属性而不是回显它。实现这一

foreach($xml->channel->item as $entry){ 
    $psg = $item->children($ns['psg']); 
    $title = (string) $item->title; 
    $duration = (string) $psg->duration; 
} 
+0

您是否尝试过使用从http://php.net/manual/en/simplexmlelement.children.php方法'children',你在命名空间中通过,并告诉它这是一个前缀,以得到那个节点? – Andy

+0

嗨!这个网站的惯例是问题和答案是分开的,[即使这意味着回答你自己的问题](http://stackoverflow.com/help/self-answer)。因此,您添加的“更新”应该是一个答案,然后您可以接受,向未来的读者展示这是解决问题的方法。你可以对罗比Averill的回答表示赞赏。 – IMSoP

回答

0

一种方法是使用XPath with namespaces组合:

$xml = new SimpleXMLElement($source, null, true); 
$xml->registerXPathNamespace('psg', 'http://b3000.example.net:3000/psg_namespace/'); 

foreach ($xml->xpath('//item/psg:duration') as $duration) { 
    echo $duration, PHP_EOL; 
} 

如果你不想字面上声明命名空间,您可以从文档中检索它,并将其添加/他们动态:

foreach ($xml->getDocNamespaces() as $key => $namespace) { 
    $xml->registerXPathNamespace($key, $namespace); 
}