将嵌套的标签值推入PHP数组


Push nested tag value into PHP array

如何使用PHP DOM将sample_id值与firstsamples一起推入数组?

我已经尝试添加另一个foreach循环,但我得到各种通知,如

Trying to get property of non-object
XML>
<?xml version="1.0" encoding="ISO-8859-1"?>
<maintable>
  <group>
    <first>text1</first>
    <second>text2</second>
    <samples a="link" b="link">
      <sample_id>000555</sample_id>
    </samples>
  </group>
  <group>
    <first>text3</first>
    <second>text4</second>
    <samples a="link" b="link">
      <sample_id>111000</sample_id>
    </samples>
  </group>  
</maintable> 
PHP

<?php
$text = file_get_contents($file);
$content = iconv('UTF-8', 'UTF-8//IGNORE', $text);
$xml = new DOMDocument('1.0', 'ISO-8859-1');
$xml->loadXML($content);
$xpath = new DOMXPath( $xml );

$query = '/maintable/group[first="text3"]';                 
$nodes = $xpath->query( $query );

$var = array();
foreach( $nodes as $k => $node )
{
    foreach( $node->childNodes as $cnode )
    {
        if ($cnode->nodeName == 'first')
        {
                $var[$k]["first"] = (string)$cnode->textContent;
        }
        if ($cnode->nodeName == 'samples')
        {
                $var[$k]["samp_url"] = (string)$cnode->getAttribute("a");
        }
        if ($cnode->nextSibling->nodeName == 'sample_id')
        {
                $var[$k]["sample_id"] = (string)$cnode->nextSibling->textContent;
        }
    }   
}
//print_r($cnode->childNodes);
?>

尝试遍历nodeList

$var = array();
$nodes = $xpath->evaluate('/maintable/group[first="text3"]');
foreach ($nodes as $node) 
{
   foreach( $node->childNodes as $cnode )
   {
       if (is_array($cnode))
       {
           foreach( $cnode->childNodes as $cn )
           {
               $var[]["sample_id"] = (string)$cn->textContent;
           }
       }
   }   
}
var_dump($var);

DOMXpath::query()只能返回节点列表,DOMXpath::evaluate()也可以返回标量。query()/evaluate()的第二个参数是上下文节点。如果提供了,Xpath表达式将是相对于它的。

因此,您可以首先选择节点,迭代列表并再次使用evaluate()来获取值:

$xml = new DOMDocument();
$xml->loadXML($content);
$xpath = new DOMXPath($xml);
$results = [];
$nodes = $xpath->evaluate('/maintable/group[first="text3"]');
foreach ($nodes as $node) {
  $results[] = [
    'first' => $xpath->evaluate('string(first)', $node),
    'sample_url' => $xpath->evaluate('string(samples/@a)', $node),
    'sample_id' => $xpath->evaluate('string(samples/sample_id)', $node)
  ];
}
var_dump($results);

输出:https://eval.in/171656

array(1) {
  [0]=>
  array(3) {
    ["first"]=>
    string(5) "text3"
    ["sample_url"]=>
    string(4) "link"
    ["sample_id"]=>
    string(6) "111000"
  }
}

只从文档中获取样本id也可以:

var_dump(
  $xpath->evaluate('string(/maintable/group[first="text3"]/samples/sample_id)')
);
输出:

string(6) "111000"

您可以使用这个XPath查询来选择您需要的正确元素:

/maintable/group/first[text()="text3"]/../samples/sample_id

解释:

/maintable                # from the top of the document, select the maintable element
/group                    # select group element, child of maintable
/first[text()="text3"]    # select 'first' element, child of group with text = 'text3'
/..                       # move up to the parent of the 'first' element
/samples                  # find samples element, child of this parent
/sample_id                # find sample_id element, child of this parent

然后您可以通过使用$node->nodeValue推送文本值(样本id)。例子:

$query = '/maintable/group/first[text()="text3"]/../samples/sample_id';                 
$nodes = $xpath->query($query);
$var = array();
foreach($nodes as $k => $node) {
    $var[] = $node->nodeValue;
}
print_r($var);
输出:

Array
(
    [0] => 111000
)

这是一篇学习如何使用XPath选择器的好文章。