如何使用PHP DOM以及sample_id
和first
将samples
值推送到数组中?
我尝试添加另一个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);
答案 0 :(得分:2)
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);
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"
答案 1 :(得分:1)
您可以使用此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
)
Here's a good read了解如何使用XPath选择器。