使用 SimpleXML 访问具有 PHP 的特定 XML-节点
Accessing a specific XML-node with PHP using SimpleXML
最近我 运行 遇到一个使用简单xml 的问题。
我想要做的是获取多次出现的嵌套节点的值。
xml 看起来有点像这样:
<response>
<album id="123">
[...]
<duration>
<value format="seconds">2576</value>
<value format="mm:ss">42:56</value>
<value format="hh:mm:ss">00:42:56</value>
<value format="xs:duration">PT42M56S</value>
</duration>
[...]
</album>
</response>
具体来说,我需要 <value format="hh:mm:ss">
节点的值。
所以我有一个对象的引用,看起来有点像这样:
$this->webservice->album->duration->value;
现在,如果我 var_dump 这个结果将是:
object(SimpleXMLElement)#117 (5) {
["@attributes"]=> array(1) {
["format"]=> string(7) "seconds"
}
[0]=> string(4) "2576"
[1]=> string(5) "42:56"
[2]=> string(8) "00:42:56"
[3]=> string(8) "PT42M56S"
}
我不明白这个输出,因为它采用第一个节点(秒)的格式属性并继续数组中的节点值,同时完全忽略以下节点的格式属性。
此外,如果我执行以下操作:
$this->webservice->album->duration->value[2];
结果是:
object(SimpleXMLElement)#108 (1) {
["@attributes"]=> array(1) {
["format"]=> string(8) "hh:mm:ss"
}
}
我根本没有要解决的价值。
我也尝试通过以下方式使用 xpath:
$this->webservice->album->duration->xpath('value[@format="hh:mm:ss"]');
这导致:
array(1) {
[0]=> object(SimpleXMLElement)#116 (1) {
["@attributes"]=> array(1) {
["format"]=> string(8) "hh:mm:ss"
}
}
}
所以我的问题是:
我究竟做错了什么? xD
提前感谢您提供任何有用的建议:)
你的错误在于过于信任var_dump
,而不是尝试使用基于the examples in the manual的元素。
第一次尝试时,您访问了 $duration_node->value
;这可以通过几种不同的方式使用:
- 如果您使用
foreach($duration_node->value as $value_node)
对其进行迭代,您将依次获得每个 <value>
元素
- 您可以通过索引访问特定元素,例如
$duration_node->value[2]
第三个元素
- 如果您将其视为单个元素,SimpleXML 假定您需要第一个元素,即
echo $duration_node->value
与 echo $duration_node->value[0]
相同
您的第二个示例运行良好 - 它找到了具有属性 format="hh:mm:ss"
的 <value>
元素。 xpath()
方法总是 returns 一个数组,因此您需要检查它是否为空,然后查看第一个元素。
一旦您拥有了正确的元素,访问其文本内容就像将其转换为字符串 ((string)$foo
) 一样简单,或者将其传递给始终需要字符串的对象(例如 echo
).
所以这行得通:
$xpath_results = $this->webservice->album->duration->xpath('value[@format="hh:mm:ss"]');
if ( count($xpath_results) != 0 ) {
$value = (string)$xpath_results[0];
}
就像这样:
foreach ( $this->webservice->album->duration->value as $value_node ) {
if ( $value_node['format'] == 'hh:mm:ss' ) {
$value = (string)$value_node;
break;
}
}
最近我 运行 遇到一个使用简单xml 的问题。 我想要做的是获取多次出现的嵌套节点的值。 xml 看起来有点像这样:
<response>
<album id="123">
[...]
<duration>
<value format="seconds">2576</value>
<value format="mm:ss">42:56</value>
<value format="hh:mm:ss">00:42:56</value>
<value format="xs:duration">PT42M56S</value>
</duration>
[...]
</album>
</response>
具体来说,我需要 <value format="hh:mm:ss">
节点的值。
所以我有一个对象的引用,看起来有点像这样:
$this->webservice->album->duration->value;
现在,如果我 var_dump 这个结果将是:
object(SimpleXMLElement)#117 (5) {
["@attributes"]=> array(1) {
["format"]=> string(7) "seconds"
}
[0]=> string(4) "2576"
[1]=> string(5) "42:56"
[2]=> string(8) "00:42:56"
[3]=> string(8) "PT42M56S"
}
我不明白这个输出,因为它采用第一个节点(秒)的格式属性并继续数组中的节点值,同时完全忽略以下节点的格式属性。
此外,如果我执行以下操作:
$this->webservice->album->duration->value[2];
结果是:
object(SimpleXMLElement)#108 (1) {
["@attributes"]=> array(1) {
["format"]=> string(8) "hh:mm:ss"
}
}
我根本没有要解决的价值。
我也尝试通过以下方式使用 xpath:
$this->webservice->album->duration->xpath('value[@format="hh:mm:ss"]');
这导致:
array(1) {
[0]=> object(SimpleXMLElement)#116 (1) {
["@attributes"]=> array(1) {
["format"]=> string(8) "hh:mm:ss"
}
}
}
所以我的问题是: 我究竟做错了什么? xD
提前感谢您提供任何有用的建议:)
你的错误在于过于信任var_dump
,而不是尝试使用基于the examples in the manual的元素。
第一次尝试时,您访问了 $duration_node->value
;这可以通过几种不同的方式使用:
- 如果您使用
foreach($duration_node->value as $value_node)
对其进行迭代,您将依次获得每个<value>
元素 - 您可以通过索引访问特定元素,例如
$duration_node->value[2]
第三个元素 - 如果您将其视为单个元素,SimpleXML 假定您需要第一个元素,即
echo $duration_node->value
与echo $duration_node->value[0]
相同
您的第二个示例运行良好 - 它找到了具有属性 format="hh:mm:ss"
的 <value>
元素。 xpath()
方法总是 returns 一个数组,因此您需要检查它是否为空,然后查看第一个元素。
一旦您拥有了正确的元素,访问其文本内容就像将其转换为字符串 ((string)$foo
) 一样简单,或者将其传递给始终需要字符串的对象(例如 echo
).
所以这行得通:
$xpath_results = $this->webservice->album->duration->xpath('value[@format="hh:mm:ss"]');
if ( count($xpath_results) != 0 ) {
$value = (string)$xpath_results[0];
}
就像这样:
foreach ( $this->webservice->album->duration->value as $value_node ) {
if ( $value_node['format'] == 'hh:mm:ss' ) {
$value = (string)$value_node;
break;
}
}