php - 命名空间的 XPath 搜索每隔一个节点选择一次

标签 php xpath xml-namespaces

在下面的代码中,我希望它选择每个节点,但它只选择每个第二个节点。这是正确的行为还是错误?

<?php
$doc = new DOMDocument('1.0', 'UTF-8');
$doc->loadXML('<root xmlns:ns="foo" ns:id="1"><one/><two/><three/><four/><five/></root>');
$finder = new DOMXPath($doc);
$nodes = $finder->query("//*[namespace::ns]");
foreach ($nodes as $n) {
  var_dump($doc->saveXML($n, LIBXML_NOEMPTYTAG));
}
?>

输出:
string '<root xmlns:ns="foo" ns:id="1"><one></one><two></two><three></three><four></four><five></five></root>' (length=101)
string '<two></two>' (length=11)
string '<four></four>' (length=13)

最佳答案

这似乎是 PHP 使用的 libxml 中的一个错误。结果是根、二、四中的名称。

使用 //*[namespace::*] 会更奇怪,然后您将获得根节点和节点一、三、五。

尽管所有子节点都继承了命名空间,但这样做似乎存在一些错误的实现。

使用以下 xslt 会生成所有所需的节点:

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:template match="/">
    <matches>
      <xsl:copy-of select="//*[namespace::ns]"/>
    </matches>
  </xsl:template>
</xsl:stylesheet>

XPath 本身虽然可以更改为//* 以选择所有节点 - 无论命名空间如何。同样,正如 kjhughes 指出的那样,您并没有真正为节点使用命名空间,而只是为属性使用命名空间。

关于php - 命名空间的 XPath 搜索每隔一个节点选择一次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30480738/

相关文章:

PHP套接字编程

javascript - 使用xpath从json对象快速检索数据

c# - 开源C#XPath 2.0过滤器

php - 为什么 `rename`删除源文件失败,而 `unlink`有效

php - 如何根据where条件值创建mysql查询结果?

PHP 日期函数跳过二月。有人知道解决此日期错误的方法吗?

r - 为什么 "//*"是我使用 XML 包在 R 中解析此 XML 时唯一有效的 xPath 查询?

xml - 使用 T-SQL 更新多个 XML 节点

jsf - 将 XML 命名空间声明提取到单独的标记文件/标记库中

java - 如何在 Java 中删除 XML 命名空间