【问题标题】:Retrieving XML values from namespace elements with PHP使用 PHP 从命名空间元素中检索 XML 值
【发布时间】:2015-11-16 04:34:45
【问题描述】:

请有人解释一下如何遍历this xml 中的<entry> 标记,以便echo 所有带有d: 前缀的元素。

下面的作品,所以我在正确的路线:

$url = "http://www.treasury.gov/resource-center/data-chart-center/interest-rates/pages/XmlView.aspx?data=yieldyear&year=2015";
$xml = simplexml_load_file($url);

foreach( $xml->entry as $entry ) {

   $element = $xml->entry->children();
        foreach( $element as $name=>$x ) {
             echo $name, '=', $x, "\n";
         }
}

但我正在努力处理 <content> 元素。

当我将$element 更新为= $xml->entry->content->children(); 时,它不起作用。

请有人帮我调试一下吗?

【问题讨论】:

  • 这个话题已经解决了before你可以使用搜索查看一些答案

标签: php xml namespaces


【解决方案1】:

你看错了。实际的命名空间 (http://schemas.microsoft.com/ado/2007/08/dataservices) 就是您所知道的。前缀特定于元素及其后代 - 直到它被重新定义。它对于元素节点也是可选的。以下树元素都具有相同的命名空间:

  • <f:foo xmlns:f="urn:foo"/>
  • <bar:foo xmlns:bar="urn:foo"/>
  • <foo xmlns="urn:foo"/>

每个元素都解析为命名空间urn:foo 内名称为foo 的节点。你可以读成{urn:foo}foo

如果您查看方法的文档,这里有许多方法具有实际的命名空间参数,因此您不必知道前缀。对于 XPath,您可以注册自己的前缀:

$url = "http://www.treasury.gov/resource-center/data-chart-center/interest-rates/pages/XmlView.aspx?data=yieldyear&year=2015";
$element = simplexml_load_file($url);

$element->registerXPathNamespace(
  'atom', 'http://www.w3.org/2005/Atom'
);
$element->registerXpathNamespace(
  'meta', 'http://schemas.microsoft.com/ado/2007/08/dataservices/metadata'
);

foreach ($element->xpath('//atom:entry/atom:content/meta:properties') as $properties) {
  $properties->registerXpathNamespace('data', 'http://schemas.microsoft.com/ado/2007/08/dataservices');
  echo $properties->xpath('data:Id')[0], "\n";
  echo $properties->xpath('data:NEW_DATE')[0], "\n\n";
}

输出:

6257
2015-01-02T00:00:00

6258
2015-01-05T00:00:00

6259
2015-01-06T00:00:00

6260
2015-01-07T00:00:00

6261
2015-01-08T00:00:00
...

您必须在要调用xpath() 的元素上注册前缀。我在示例中使用了不同的前缀,因此您可以看到您不必知道前缀 - 只需知道命名空间本身。

在 DOM 中它是一个单独的对象,DOMXpath:evaluate() 可以直接返回标量值。

$document = new DOMDocument();
$document->loadXml($xml);
$xpath = new DOMXpath($document);
$xpath->registerNamespace('atom', 'http://www.w3.org/2005/Atom');
$xpath->registerNamespace('meta', 'http://schemas.microsoft.com/ado/2007/08/dataservices/metadata');
$xpath->registerNamespace('data', 'http://schemas.microsoft.com/ado/2007/08/dataservices');

foreach ($xpath->evaluate('//atom:entry/atom:content/meta:properties') as $properties) {
  echo $xpath->evaluate('string(data:Id)', $properties), "\n";
  echo $xpath->evaluate('string(data:NEW_DATE)', $properties), "\n\n";
}

【讨论】:

  • 很好的答案,谢谢。我进入了更深入的内容,因此更详细地了解了前缀/命名空间。我有一个关注你的Q! //atom:entry/atom:content/m:properties 也可以在 foreach 行中工作吗?我为此创建了一个新问题:stackoverflow.com/questions/33809590/…
  • 你已经得到了这个问题的正确答案——我赞成。文档和 Xpath 引擎都使用命名空间的前缀。两者都在内部将它们解析为命名空间并使用命名空间 uri。有的库会自动注册上下文节点的命名空间,但是这个很脆弱,自己注册就好了。
【解决方案2】:

与您的other question 一样,您可以使用xpath 的方法:

$xml = simplexml_load_file($url);

foreach ($xml->entry as $entry) { // loop over the entries
    print_r($entry->xpath('//d:BC_3MONTH')); // gives you the actual BC_3MONTH
    print_r($entry->xpath('//d:Id')); // the actual ID
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多