如何从命名空间和非命名空间XML的混合中获取值

时间:2017-02-02 03:17:45

标签: php namespaces simplexml

鉴于XML和相关的PHP,下面如何以与我能够获取非命名空间值相同的方式获取命名空间值?我一直在谈论其他一些关于这个问题的SE QAs,但似乎无法做到这一点。感谢帮助。 :)

<?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;
}

1 个答案:

答案 0 :(得分: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);
}