为什么 SimpleXMLElement 无法找到 XML 文件的内容?
Why is SimpleXMLElement not able to find contents of XML file?
我需要使用 php 解析从第三方收到的 xml 文档。我无法要求文档的维护者修复其结构。当我使用 simplexml_load_file
解析文档时,XML 文档是空的。
这是我所看到的精简示例。
我的-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 中第一个文档的最佳方法是什么?
问题不是数据未加载,而是子元素位于不同的命名空间。
$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
"
}
这无需使用命名空间即可输出子项。
我需要使用 php 解析从第三方收到的 xml 文档。我无法要求文档的维护者修复其结构。当我使用 simplexml_load_file
解析文档时,XML 文档是空的。
这是我所看到的精简示例。
我的-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 中第一个文档的最佳方法是什么?
问题不是数据未加载,而是子元素位于不同的命名空间。
$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
"
}
这无需使用命名空间即可输出子项。