简体   繁体   English

使用SimpleXML通过PHP访问特定的XML节点

[英]Accessing a specific XML-node with PHP using SimpleXML

lately i ran into a problem using simplexml. 最近我在使用simplexml时遇到了问题。 What i want to do is to get a value of a nested node that occurs multiple times. 我想做的是获取多次出现的嵌套节点的值。 The xml looks somewhat like this: 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>

Specifically i need the value of the the <value format="hh:mm:ss"> node. 具体来说,我需要<value format="hh:mm:ss">节点的值。

So I have a reference to the object that looks somewhat like this: 因此,我有一个对该对象的引用,看起来像这样:

$this->webservice->album->duration->value;

Now, if i var_dump this the result will be: 现在,如果我使用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" 
}

I do not understand this output, since it takes the format-attribute of the first node (seconds) and continues with the node-values in the array, while ignoring the format-attribute of the following nodes completely. 我不理解此输出,因为它采用第一个节点的格式属性(秒)并继续使用数组中的节点值,而完全忽略了后续节点的格式属性。

Furthermore, if i do the following: 此外,如果我执行以下操作:

$this->webservice->album->duration->value[2];

it results in: 结果是:

object(SimpleXMLElement)#108 (1) { 
  ["@attributes"]=> array(1) { 
    ["format"]=> string(8) "hh:mm:ss" 
  } 
}

where i haven't got a value to address at all. 我根本没有值要解决的地方。

I tried to use xpath instead too in the following way: 我也尝试通过以下方式使用xpath:

$this->webservice->album->duration->xpath('value[@format="hh:mm:ss"]');

which results in: 结果是:

array(1) { 
  [0]=> object(SimpleXMLElement)#116 (1) { 
    ["@attributes"]=> array(1) { 
      ["format"]=> string(8) "hh:mm:ss" 
    } 
  } 
}

So my question is: What am I doing wrong? 所以我的问题是:我在做什么错? xD xD

Thanks in advance for any helpful advice :) 在此先感谢您提供任何有用的建议:)

Your mistake is in trusting var_dump too completely, rather than trying to use the elements based on the examples in the manual . 您的错误是过于完全信任var_dump ,而不是尝试根据手册中的示例使用元素。

On your first attempt, you accessed $duration_node->value ; 首次尝试时,您访问了$duration_node->value this can be used in a few different ways: 可以通过几种不同的方式使用它:

  • if you iterate over it with foreach($duration_node->value as $value_node) , you get each of the <value> elements in turn 如果使用foreach($duration_node->value as $value_node)对其进行迭代,则foreach($duration_node->value as $value_node)获得每个<value>元素
  • you can access specific elements by index, eg $duration_node->value[2] for the 3rd element 您可以按索引访问特定元素,例如,第三个元素的$duration_node->value[2]
  • if you treat it as a single element, SimpleXML assumes you want the first element, ie echo $duration_node->value is the same as echo $duration_node->value[0] 如果将其视为单个元素,则SimpleXML会假定您要第一个元素,即echo $duration_node->valueecho $duration_node->value[0]

Your second example worked fine - it found the <value> element with an attribute format="hh:mm:ss" . 您的第二个示例运行良好-它找到了带有属性format="hh:mm:ss"<value>元素。 The xpath() method always returns an array, so you need to check that it's not empty then look at the first element. xpath()方法始终返回一个数组,因此您需要检查它是否不为空,然后查看第一个元素。

Once you have the right element, accessing its text content is as simple as casting it to a string ( (string)$foo ), or passing it to something that always needs a string (eg echo ). 获得正确的元素后,访问其文本内容就像将其强制转换为字符串( (string)$foo )或将其传递给始终需要字符串的东西一样简单(例如echo )。

So this would work: 所以这将工作:

$xpath_results = $this->webservice->album->duration->xpath('value[@format="hh:mm:ss"]');
if ( count($xpath_results) != 0 ) {
    $value = (string)$xpath_results[0];
}

As would this: 就像这样:

foreach ( $this->webservice->album->duration->value as $value_node ) {
    if ( $value_node['format'] == 'hh:mm:ss' ) {
        $value = (string)$value_node;
        break;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM