我需要使用php解析我从第三方收到的xml文档。我无法要求文档的维护者修复其结构。当我使用simplexml_load_file
解析文档时,XML文档是空的。
这是我所看到的一个精简的例子。
MY-file.xml:
<?xml version="1.0" encoding="utf-8"?>
<DataSet>
<diffgr:diffgram xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
aaa
</diffgr:diffgram>
</DataSet>
我像这样(从命令行)处理它:
php > $xml = simplexml_load_file('my-file.xml');
php > print_r($xml);
SimpleXMLElement Object
(
)
我期待xml结构通过print_r
显示。
实际上,当我删除命名空间声明时,事情似乎有效(尽管有一些预期的XML解析警告):
我的文件-nonamespace.xml:
<?xml version="1.0" encoding="utf-8"?>
<DataSet>
<diffgr:diffgram>
aaa
</diffgr:diffgram>
</DataSet>
在命令行上以相同的方式处理它(删除了警告):
php > $xml = simplexml_load_file('my-file-nonamespace.xml');
// a bunch of xml parse warnings
php > print_r($xml);
SimpleXMLElement Object
(
[diffgr:diffgram] =>
aaa
)
因此,问题与无效的名称空间声明有关。我可以在解析之前使用文件上的正则表达式来删除命名空间声明,但这不是我想要的方向。
在PHP中正确解析第一个文档的最佳方法是什么?
答案 0 :(得分:0)
问题不在于数据未加载,而是子元素位于不同名称空间的事实。
$xml = simplexml_load_file('my-file.xml');
var_dump($xml->children("diffgr", true));
这将从当前元素中选择特定命名空间中的子项。
请注意,您应该使用URI,因为前缀可能会更改,但这只是为了表明数据存在。
修改强> 如果XML存在问题,那么第一阶段是忽略错误,然后检查加载的内容......
libxml_use_internal_errors(true);
$xml = simplexml_load_file('my-file.xml');
echo $xml->asXML();
这将让您了解结果的状态,即使加载也是如此。一个简单的例子是......
libxml_use_internal_errors(true);
$xml = simplexml_load_file('my-file.xml');
echo $xml->asXML();
var_dump($xml->children());
使用..
<?xml version="1.0" encoding="utf-8"?>
<DataSet>
<diffgr:diffgram>
aaa
</diffgr:diffgram>
</DataSet>
注意命名空间是如何存在的,但是没有声明命名空间。输出是......
<?xml version="1.0" encoding="utf-8"?>
<DataSet>
<diffgr:diffgram>
aaa
</diffgr:diffgram>
</DataSet>
/home/nigel/workspace2/Test/t1.php:22:
class SimpleXMLElement#2 (1) {
public $diffgr:diffgram =>
string(11) "
aaa
"
}
这将输出子节点,而不必使用命名空间。