我有一个非常长的XML,我正在PHP中使用simplexml_load_string
来处理它。我面临着一个非常奇怪的行为。
这是XML,我已经缩短了这一部分,这很麻烦。
<?xml version="1.0" encoding="UTF-8"?>
<test><Customer></Customer><Comments><CustomerComment></CustomerComment></Comments></test>
我将此值保存为string
。这是我的PHP代码。
$xml = '<?xml version="1.0" encoding="UTF-8"?>
<test><Customer></Customer><Comments><CustomerComment></CustomerComment></Comments></test>';
$xml = simplexml_load_string($xml);
var_dump($xml);
这是输出
object(SimpleXMLElement)#1 (2) {
["Customer"]=>
object(SimpleXMLElement)#2 (0) {
}
["Comments"]=>
object(SimpleXMLElement)#3 (1) {
[0]=>
object(SimpleXMLElement)#4 (0) {
}
}
}
我不知道这个简单的代码出了什么问题,也不知道为什么它不能维护子名称CustomerComment
。谷歌搜索了很多,还找不到任何相关的东西。
奇怪的是,我已经从XML树的根中删除了Customer
子项,并且它正在正确地获取子项名称。
php > $xml = '<?xml version="1.0" encoding="UTF-8"?>
php ' <order><Comments><CustomerComment></CustomerComment></Comments></order>';
php > $xml = simplexml_load_string($xml);
php > var_dump($xml);
object(SimpleXMLElement)#1 (1) {
["Comments"]=>
object(SimpleXMLElement)#3 (1) {
["CustomerComment"]=>
object(SimpleXMLElement)#2 (0) {
}
}
}
现在真正奇怪的部分是,如果我按照打破XML树
<?xml version="1.0" encoding="UTF-8"?>
<order>
<Customer></Customer>
<Comments>
<CustomerComment></CustomerComment>
</Comments>
</order>
这是var_dump
。
object(SimpleXMLElement)#1 (2) {
["Customer"]=>
object(SimpleXMLElement)#3 (0) {
}
["Comments"]=>
object(SimpleXMLElement)#2 (1) {
["CustomerComment"]=>
object(SimpleXMLElement)#4 (0) {
}
}
}
它得到了正确的子名称,但XML与第一个示例相同(除了换行符)
请有人指出,这里出了什么问题?,以及如何解决这个问题。我猜问题是在一行中有相同的子名称(此时为Customer
)。
我能想到的唯一可能的解决方案是在我的XML字符串中用>'n
替换>
。
重要的是要认识到SimpleXML不会将XML转换为对象的数组或层次结构。与DOM一样,SimpleXML是一个用于访问XML的API(但使用起来更好!);因此,使用var_dump
,或者盲目地转换为JSON,将不会给出有用的结果。相反,使用SimpleXML提供的API从XML文档中提取您实际需要的数据。
在这种情况下,您会发现作为API,$xml->Comments->CustomerComment
和$xml->Comments[0]->CustomerComment
都返回相同的元素(如果您事先不知道是否有人要添加第二个Comments
元素,这很好)。在转储输出(或转换为平面数组)时,SimpleXML必须猜测要显示其中的哪一个。PHP的某些版本似乎有一个错误,它显示了0
,而不是直接跳到CustomerComment
,但简单的事实是无论如何都不应该依赖它,只访问您知道需要的节点即可。