PHP simplexml:为什么xpath停止工作?

Dav*_*ogt 12 php xml xpath simplexml

供应商稍微更改了XML标题后发生了一件奇怪的事情.我曾经能够使用xpath读取内容,但现在我甚至无法得到回复

$xml->xpath('/');
Run Code Online (Sandbox Code Playgroud)

他们改变了这个......

<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE NewsML SYSTEM "http://www.newsml.org/dl.php?fn=NewsML/1.2/specification/NewsML_1.2.dtd" [
<!ENTITY % nitf SYSTEM "http://www.nitf.org/IPTC/NITF/3.4/specification/dtd/nitf-3-4.dtd">
%nitf;
]>
<NewsML>
...
Run Code Online (Sandbox Code Playgroud)

对此:

<?xml version="1.0" encoding="iso-8859-1"?>
<NewsML
  xmlns="http://iptc.org/std/NewsML/2003-10-10/"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://iptc.org/std/NewsML/2003-10-10/ http://www.iptc.org/std/NewsML/1.2/specification/NewsML_1.2.xsd http://iptc.org/std/NITF/2006-10-18/   http://contentdienst.pressetext.com/misc/nitf-3-4.xsd"
>
...
Run Code Online (Sandbox Code Playgroud)

Tom*_*lak 25

这很可能是因为他们在xmlns="http://iptc.org/std/NewsML/2003-10-10/"文档中引入了一个默认的命名空间().简而言之,SimpleXML对默认命名空间的支持并不是很好.

您可以尝试显式注册名称空间前缀:

$xml->registerXPathNamespace("n", "http://iptc.org/std/NewsML/2003-10-10/");
$xml->xpath('/n:NewsML');
Run Code Online (Sandbox Code Playgroud)

您必须调整XPath表达式以"n:"每个元素上使用前缀.以下是一些其他信息:http://people.ischool.berkeley.edu/~felix/xml/php-and-xmlns.html.

编辑:根据规范:

registerXPathNamespace()函数为下一个XPath查询创建前缀/ ns上下文.

这意味着必须在每个XPath查询之前调用它,因此包装XPath查询的函数将是自然而然的事情:

function simplexml_xpath_ns($element, $xpath, $xmlns)
{
    foreach ($xmlns as $prefix_uri)
    {
        list($prefix, $uri) = explode("=", $prefix_uri, 2);
        $element->registerXPathNamespace($prefix, $uri);
    }
    return $element->xpath($xpath);
}
Run Code Online (Sandbox Code Playgroud)

用法:

$xmlns = ["n=http://iptc.org/std/NewsML/2003-10-10/"];
$result = simplexml_xpath_ns($xml, '/n:NewsML', $xmlns);
Run Code Online (Sandbox Code Playgroud)