我正在处理的一个项目需要解析来自供应商的XML文档,但他们提供了无效的XML,该XML具有未声明名称空间的属性。当我同时尝试$node->getAttribute('prod:amount')
和$node->getAttribute('amount')
时,getAttribute($name)
会忽略它
我是做错了什么,还是有办法以某种方式伪造定义?
编辑提供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
}
在您发布的源中,缺少"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);