簡體   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