PHP从childNodes中提取getElementsByTagName

时间:2017-04-26 11:56:52

标签: php xml domdocument getelementsbytagname child-nodes

这一切都应该非常直接,但出于某种原因,它正在逃避我。

使用从文件导入的以下XML结构:

<locations>
  <devices>
    <entry>
      <serial>12345</serial>
      <hostname>FooBarA</hostname>
      <vsys>
        <entry>
          <displayname>CorpA</displayName>
          <tag>InternalA</tag>
        </entry>
      </vsys>
      </c>
    </entry>
    <entry>
      <serial>123456</serial>
      <hostname>FooBarB</hostname>
      <vsys>
        <entry>
          <displayname>CorpB</displayName>
          <tag>InternalB</tag>
        </entry>
      </vsys>
      </c>
    </entry>
  </devices>
</locations>

提取家长,应该是直截了当的:

$devices = $dom->getElementsByTagName('devices');
$data = array();
foreach($devices as $node){  // each $node = <devices> == only ONE object
  foreach($node->childNodes as $child) {  // each $child is the ENTIRE <entry>, including <entry> tag
    // I would expect this to return the <serial> out of parent <entry>, but its not
    $serial = $child->getElementsByTagName('serial') ;
    echo "\n" . $count++ . ", a" .$serial->nodeName ;    
    if ($child->nodeName == "entry") {
      // as a secondary method, I then try to extra <serial> looping through the childNodes of the parent <entry> and again, this doesn't work.
      foreach ($child->childNodes as $kid) {
        $serial = $kid->getElementsByTagName('serial') ;
        echo ", b" .$serial->nodeName ;
      }
    }
  }
}

以上打印出来:

1a, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b
2a, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b
3a, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b
4a, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b

我的实际xml文件在serial级别有更多的兄弟姐妹,因此它打印出所有额外的b ...因此这告诉我基本的foreach正在运行并且每个都正常循环遍历每个级别 - 但我无法在每个级别中提取nodeName或getElementsByTagName。

我认为两种方法中的一种,在不同的嵌套级别,会提取<serial>,但两种方法都不起作用。我在这里缺少什么?

我的期望是打印出来:

1a 12345, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b
2a 123456, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b
3a 1234567, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b
4a 12345678, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b

或者在最低限度:

1a, b 12345, b 12345, b 12345 ...
2a, b 123456, b 123456, b 123456 ...
3a, b 1234567, b 1234567, b 1234567 ...
etc etc.

1 个答案:

答案 0 :(得分:1)

getElementsByTagName返回DOMNodeList,因此您需要对其进行迭代以获取各个节点的名称:

$serials = $child->getElementsByTagName('serial') ;
foreach($serials as $serial) {
  echo "\n" . $count++ . ", a" .$serial->nodeName ;    
}

作为辅助节点,问题中的xml无效:

  • <displayname> ... </displayName>
  • <vsys> <entry> ... </entry> </c>