2014-10-20 16 views
0

我正在處理的項目需要從供應商分析XML文檔,但他們提供了具有未聲明名稱空間屬性的無效XML。 getAttribute($name)忽略它當我嘗試$node->getAttribute('prod:amount')$node->getAttribute('amount')DOMNode :: getAttribute具有未定義的名稱空間

我做錯了什麼,或者有沒有辦法僞造定義?

編輯提供XML摘錄和PHP。

XML:

<order> 
    <item id="85127" prod:id="1397" prod:amount="12.99"> 
     <desc><![CDATA[...]]></desc> 
    </item> 
    <item id="85128" prod:id="93" prod:amount="24.99"> 
     <desc><![CDATA[...]]></desc> 
    </item> 
    ... 
</order> 

PHP:

$doc = new DOMDocument; 
$doc->load('URI'); 
foreach($doc->getElementsByTagName("item") as $node) { 
    $cost = $node->getAttribute("amount"); 
    $id = $node->getAttribute("prod:id"); 
    print_r($cost); //never outputs 
} 
+0

您可以發佈XML和您使用的代碼的示例嗎?您是否聯繫過供應商,告訴他們他們的XML無效? – 2014-10-20 19:30:25

+0

供應商不支持他們的API,它是一種「便利」功能。 99%的客戶使用他們的GUI和內置集成點。不過,客戶堅持要將其添加到銷售門戶中。 – 2014-10-20 20:53:38

+0

你發佈的代碼是無效的 - 我可以從XML中獲取金額,儘管DOMDocument確實會對未聲明的命名空間提出一個棘手的問題(又稱爲負載警告)。我會有點試圖犯下最令人髮指的罪行,並將一個虛假的名稱空間聲明添加到XML中。 – 2014-10-20 21:15:06

回答

0

要知道,一些XML的意見(火狐爲例)不顯示的xmlns屬性(命名空間的定義)。如果您沒有收到錯誤消息(又稱XML有效),請打開源以檢查名稱空間定義。

在您發佈的來源中,'amount'屬性的前綴缺失,因此它不會顯示任何內容。

$cost = $node->getAttribute("prod:amount"); 

但依賴文檔中定義的命名空間前綴並不是上帝的主意。更好的方法是使用名稱空間本身。

$xml = <<<'XML' 
<order xmlns:prod="urn:products"> 
    <item id="85127" prod:id="1397" prod:amount="12.99"></item> 
    <item id="85128" prod:id="93" prod:amount="24.99"></item> 
</order> 
XML; 

const XMLNS_PROD = 'urn:products'; 

$doc = new DOMDocument; 
$doc->loadXml($xml); 
foreach($doc->getElementsByTagName("item") as $node) { 
    $cost = $node->getAttributeNS(XMLNS_PROD, "amount"); 
    $id = $node->getAttributeNS(XMLNS_PROD, "id"); 
    var_dump($id, $cost); 
} 

輸出:

string(4) "1397" 
string(5) "12.99" 
string(2) "93" 
string(5) "24.99" 

所以,如果這裏真的是沒有命名空間定義,那麼你就可以 「修復」 的通過將一個XML。這是一種解決方法,真正的解決方案是在其源頭修復XML。

$xml = str_replace('<order>', '<order xmlns:prod="urn:products">', $xml); 
$doc = new DOMDocument; 
$doc->loadXml($xml); 
相關問題