2015-01-21 97 views
1

我对XML文件中像腓循环throught 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的

回答

2

在第二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>"; 
    } 
} 

Sample Output

还是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>"; 
    } 
} 

Sample Output

+0

@DmitrijHolkin刚刚拿到个人的孩子,请查看我的修订 – Ghost 2015-01-21 11:15:08

+0

感谢之多。效果不错 – 2015-01-21 11:20:32

+0

@DmitrijHolkin很高兴这有帮助 – Ghost 2015-01-21 11:25:25

1

使用此代码:

$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>"; 
    } 
} 
+1

公告:未定义的属性:的DOMNodeList :: $项目 – 2015-01-21 11:10:40

1

DOMXpath的第二个参数::评估()是上下文节点。如果你不用斜杠启动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)。你将需要两个循环。像输出由标签*元素节点分组的项目一样。

$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 
+0

只有麻烦如何使用把每个本地名分开php文件作为数组'$ data ='\ n'“。$ xpath-> evaluate('string(id)',$ node)。”'=>'“。$ xpath-> evaluate('string(title)',$ node) ,';'_'file_put_contents(“。”。$ path。$ xpath-> evaluate('local-name(parent :: *)',$ node)。'。php','<?php $ arr = array ('。$ data。'\ n); \ n?>');'不能很好地工作 – 2015-01-21 13:11:10

+0

这不是您的原始问题中的请求,我在我的答案中添加了一个示例。 – ThW 2015-01-21 13:21:27