繁体   English   中英

忽略php中带有xpath的名称空间

[英]ignore namespace with xpath in php

我想从xml文件中提取一些标签。 xml文件可能是这样的:

<mediawiki xmlns="http://www.mediawiki.org/xml/export-0.10/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mediawiki.org/xml/export-0.10/ http://www.mediawiki.org/xml/export-0.10.xsd" version="0.10" xml:lang="de">
[... some more tags ...]
  <page>
    <title>Title 1</title>
    [... some more tags ...]
  </page>
  <page>
    <title>Title 2</title>
    [... some more tags ...]
  </page>
</mediawiki>

当我使用https://www.freeformatter.com/xpath-tester.html拉“ // title”时,一切正常,并且我收到了两个标题。

但是当我使用以下php时:

$xml = simplexml_load_file('articles.xml');
$result = $xml->xpath('//title');
var_dump($result);

结果数组为空。

我已经检查了许多类似的问题,并发现如果使用相同的URL设置registerXPathNamespace,它将可以使用。 但是,我正在阅读的XML来自几个外部来源,这些来源带有不同的软件(以上只是一个可能的示例)。 它们可能随时更改。 因此,每次打开XML时,我都需要读出URL并将其放入registerXPathNamespace中。 使它起作用的另一种方法是从XML中剥离xmlns。 如果我想要做的就是不管名称空间是什么,都提取“ title”(和其他一些)标记,那么这两个选项似乎都非常复杂。

有没有一种简单的方法告诉xpath忽略名称空间? (如果没有办法忽略它,那么避免更改URL问题的最简单,持久的解决方案是什么?)

到目前为止,我正在使用硬编码

foreach ($xml->page as $page) {
  $title = $page->title;
  //[... do something ...]
}

哪个有效。 但是我认为xpath会很方便(更灵活,不硬编码,更耐用),并想尝试一下。

您可以通配名称空间,例如//*:title

您可以从文档中获取名称空间,然后从中注册默认名称空间。 由于默认名称空间以空白键结尾,这有点麻烦,但这就是为什么从数组中获取第一个值然后使用它有点费解的原因。

因此,代码类似于:

$xml = simplexml_load_file('articles.xml');
$ns = $xml->getDocNamespaces();
$xml->registerXPathNamespace('def', array_values($ns)[0]);
$result = $xml->xpath('//def:title');
var_dump($result);

尽管选择的注册默认名称空间的解决方案有效,但它也要求我似乎毫无理由地使我的xpath查询混乱。 在我的特殊情况下,我怀疑还有许多其他情况,从文档中完全删除名称空间会更有帮助。 不幸的是,并没有出现任何的方式来做到这一点使用DOM工具在PHP,所以我不得不求助于正则表达式。 我要说的是, 我真的很讨厌这样做,因为我是一再因为使用正则表达式来操纵XML和HTML的人而不断地追求他人。

无论如何,这对我有用:

$xml = file_get_contents('my_document.xml');
$xml = preg_replace('/(xmlns|xsi)[^=]*="[^"]*" ?/i', '', $xml);
$doc = simplexml_load_string($xml);

而且,现在您可以根据需要查询xpath,而无需命名空间前缀:

$result = $xml->xpath('//title');

根据文档的不同,这可能不是一个好主意,尤其是在元素上有名称空间前缀的情况下,但是在许多基本情况下,它就可以正常工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM