Php 遍历 Xml 个节点
Php loop throught Xml nodes
我有Xml个文件
<response>
<tag1>
<item>
<id>106</id>
<title>DG</title>
</item>
<item>
<id>105</id>
<title>AC</title>
</item>
</tag1>
<tag2>
<item>
<id>1</id>
<title>DjG</title>
</item>
<item>
<id>15</id>
<title>AoC</title>
</item>
</tag2>
</response>
我正在尝试使用此代码提取 ID 和标题
$dom = new DomDocument();
$dom->load('xml.xml');
$xpath = new DOMXPath($dom);
foreach($xpath->evaluate('//response/*') as $node){
$params =$xpath->evaluate('//response/' .$node->nodeName . '/item/*');
foreach($params as $child) {
echo $node->nodeName ." = " .$child->nodeName ." = " .$child->nodeValue ."\n<br>";
}
}
但我得到这样的结果
<br>tag1 = id = 106
<br>tag1 = title = DG
<br>tag1 = id = 105
<br>tag1 = title = AC
<br>tag2 = id = 1
<br>tag2 = title = DjG
<br>tag2 = id = 15
<br>tag2 = title = AoC
但我需要这样
tag1 = 106 = DG
tag1 = 105 = AC
tag2 = 1 = DjG
tag2 = 15 = AoC
使用此代码:
$dom = new DomDocument();
$dom->load('xml.xml');
$xpath = new DOMXPath($dom);
foreach($xpath->evaluate('//response/*') as $node){
$params =$xpath->evaluate('//response/' .$node->nodeName . '/*');
foreach($params as $child)
{
echo $node->nodeName ." = " .$child->getElementsByTagName('id')->item(0)->textContent ." = " .$child->getElementsByTagName('title')->item(0)->textContent ."\n<br>";
}
}
在第二个 foreach
上,只定位 $node->nodeName
,然后在内部 foreach 目标上,每个 id 一个标题。
foreach($xpath->evaluate('//response/*') as $node) {
$tag = $node->nodeName;
$params = $xpath->evaluate("//$tag/*");
foreach($params as $child) {
$id = $xpath->evaluate('string(./id)', $child);
$title = $xpath->evaluate('string(./title)', $child);
echo $tag ." = " .$id ." = " .$title ."\n<br>";
}
}
或 SimpleXML
版本:
$xml = simplexml_load_file('xml.xml');
foreach($xml as $tag =>$node) {
foreach($node as $item => $child) {
echo $tag ." = " .$child->id ." = " .$child->title ."\n<br>";
}
}
DOMXpath::evaluate() 的第二个参数是上下文节点。如果不以斜线开始 XPath 表达式,它将相对于它。因此在循环内,您通常希望使用当前节点作为表达式的上下文。
foreach ($xpath->evaluate('/absolute-expression') as $node) {
var_dump(
$xpath->evaluate('relative-expression', $node)
);
}
XPath(不像 CSS 选择器)可以沿着不同的轴获取元素的属性。您可以通过以下方式获取父节点的本地名称(不带命名空间前缀):
local-name(parent::*)
使用它,您可以通过迭代 item
个元素的单个循环来解决问题。
示例:
$dom = new DomDocument();
$dom->loadXml($xml);
$xpath = new DOMXPath($dom);
foreach ($xpath->evaluate('//response/*/item') as $node) {
echo
$xpath->evaluate('local-name(parent::*)', $node), ' = ',
$xpath->evaluate('string(id)', $node), ' = ',
$xpath->evaluate('string(title)', $node), "\n";
}
输出:
tag1 = 106 = DG
tag1 = 105 = AC
tag2 = 1 = DjG
tag2 = 15 = AoC
仅当需要为每个一级节点(tag1,tag2)调用source时。你将需要两个循环。比如输出tag*元素节点分组的items。
$dom = new DomDocument();
$dom->loadXml($xml);
$xpath = new DOMXPath($dom);
foreach ($xpath->evaluate('//response/*') as $node) {
echo
$xpath->evaluate('local-name()', $node),
"\n--------\n";
foreach ($xpath->evaluate('item', $node) as $item) {
echo
$xpath->evaluate('string(id)', $item), ' = ',
$xpath->evaluate('string(title)', $item), "\n";
}
echo "\n";
}
输出:
tag1
--------
106 = DG
105 = AC
tag2
--------
1 = DjG
15 = AoC
我有Xml个文件
<response>
<tag1>
<item>
<id>106</id>
<title>DG</title>
</item>
<item>
<id>105</id>
<title>AC</title>
</item>
</tag1>
<tag2>
<item>
<id>1</id>
<title>DjG</title>
</item>
<item>
<id>15</id>
<title>AoC</title>
</item>
</tag2>
</response>
我正在尝试使用此代码提取 ID 和标题
$dom = new DomDocument();
$dom->load('xml.xml');
$xpath = new DOMXPath($dom);
foreach($xpath->evaluate('//response/*') as $node){
$params =$xpath->evaluate('//response/' .$node->nodeName . '/item/*');
foreach($params as $child) {
echo $node->nodeName ." = " .$child->nodeName ." = " .$child->nodeValue ."\n<br>";
}
}
但我得到这样的结果
<br>tag1 = id = 106
<br>tag1 = title = DG
<br>tag1 = id = 105
<br>tag1 = title = AC
<br>tag2 = id = 1
<br>tag2 = title = DjG
<br>tag2 = id = 15
<br>tag2 = title = AoC
但我需要这样
tag1 = 106 = DG
tag1 = 105 = AC
tag2 = 1 = DjG
tag2 = 15 = AoC
使用此代码:
$dom = new DomDocument();
$dom->load('xml.xml');
$xpath = new DOMXPath($dom);
foreach($xpath->evaluate('//response/*') as $node){
$params =$xpath->evaluate('//response/' .$node->nodeName . '/*');
foreach($params as $child)
{
echo $node->nodeName ." = " .$child->getElementsByTagName('id')->item(0)->textContent ." = " .$child->getElementsByTagName('title')->item(0)->textContent ."\n<br>";
}
}
在第二个 foreach
上,只定位 $node->nodeName
,然后在内部 foreach 目标上,每个 id 一个标题。
foreach($xpath->evaluate('//response/*') as $node) {
$tag = $node->nodeName;
$params = $xpath->evaluate("//$tag/*");
foreach($params as $child) {
$id = $xpath->evaluate('string(./id)', $child);
$title = $xpath->evaluate('string(./title)', $child);
echo $tag ." = " .$id ." = " .$title ."\n<br>";
}
}
或 SimpleXML
版本:
$xml = simplexml_load_file('xml.xml');
foreach($xml as $tag =>$node) {
foreach($node as $item => $child) {
echo $tag ." = " .$child->id ." = " .$child->title ."\n<br>";
}
}
DOMXpath::evaluate() 的第二个参数是上下文节点。如果不以斜线开始 XPath 表达式,它将相对于它。因此在循环内,您通常希望使用当前节点作为表达式的上下文。
foreach ($xpath->evaluate('/absolute-expression') as $node) {
var_dump(
$xpath->evaluate('relative-expression', $node)
);
}
XPath(不像 CSS 选择器)可以沿着不同的轴获取元素的属性。您可以通过以下方式获取父节点的本地名称(不带命名空间前缀):
local-name(parent::*)
使用它,您可以通过迭代 item
个元素的单个循环来解决问题。
示例:
$dom = new DomDocument();
$dom->loadXml($xml);
$xpath = new DOMXPath($dom);
foreach ($xpath->evaluate('//response/*/item') as $node) {
echo
$xpath->evaluate('local-name(parent::*)', $node), ' = ',
$xpath->evaluate('string(id)', $node), ' = ',
$xpath->evaluate('string(title)', $node), "\n";
}
输出:
tag1 = 106 = DG
tag1 = 105 = AC
tag2 = 1 = DjG
tag2 = 15 = AoC
仅当需要为每个一级节点(tag1,tag2)调用source时。你将需要两个循环。比如输出tag*元素节点分组的items。
$dom = new DomDocument();
$dom->loadXml($xml);
$xpath = new DOMXPath($dom);
foreach ($xpath->evaluate('//response/*') as $node) {
echo
$xpath->evaluate('local-name()', $node),
"\n--------\n";
foreach ($xpath->evaluate('item', $node) as $item) {
echo
$xpath->evaluate('string(id)', $item), ' = ',
$xpath->evaluate('string(title)', $item), "\n";
}
echo "\n";
}
输出:
tag1
--------
106 = DG
105 = AC
tag2
--------
1 = DjG
15 = AoC