在PHP中处理XML时只读取第一个元素

时间:2011-03-10 09:54:29

标签: php xml

我在使用PHP读取XML文件时遇到了一些麻烦。我不是很擅长PHP,所以我使用这段代码:Article

这是我正在尝试阅读的XML文件:http://pastebin.com/2dtMp5VH

<?xml version="1.0" encoding="UTF-8"?>
<contentdata>
    <Games>
    <numberof>2</numberof>
        <nameof>
            <n1>Game1</n1>
            <n2>Game2</n2>
        </nameof>
     </Games>
     <Software>
    <numberof>1</numberof>
        <nameof>
            <n1>Software1</n1>
        </nameof>
     </Software>
</contentdata>

这是我的PHP脚本,基于我给出的文章:http://pastebin.com/d29ejxSJ

$objDOM = new DOMDocument(); 
$objDOM->load("content.xml");
$note = $objDOM->getElementsByTagName("Games"); 

foreach( $note as $value ) 
{ 
    $numberof = $value->getElementsByTagName("numberof"); 
    $numberof_  = $numberof->item(0)->nodeValue; 
    echo($numberof_." games found!<br />");

    $numberof = (integer)$numberof_;
    $nameof = $value->getElementsByTagName("nameof");
    $i = 1;
    foreach($nameof as $value2)
    {
        $n = (string)$i;
        $nameof_[$i] = $value2->getElementsByTagName("n".$n);
        $nameof_[$i] = $nameof_[$i]->item(0)->nodeValue;
        echo(((string)$i).": ".$nameof_[$i]."<br />");
        $i++;
    }
} 

输出应该是这样的:
找到2个游戏!
1:Game1
2:Game2

但是,出于某种原因,它只输出以下内容:
找到2个游戏!
1:Game1

我的代码出了什么问题?怎么解决这个问题?

6 个答案:

答案 0 :(得分:1)

就像@chris说的那样,我认为你在坏节点上做了第二个foreach。 您的第二个foreach目标:nameof而不是他的内容(n1,n2,...)

使用Simple XML:

$Games = $value->getElementsByTagName("nameof")->children();
foreach($Games as $value2)
{
   // Your code to parse <nX>
}

答案 1 :(得分:0)

查看SimpleXML函数:simplexml_load_string

答案 2 :(得分:0)

我们需要查看您的XML,真正帮助解决这个问题......

我认为你可能会混淆元素和属性。简而言之,XML就是这样构成的

<tagname attr1=5 attr2='arf'> BODY HERE </tagname>

在您的情况下,我认为numberofnameof根本不是元素。它们似乎是属于Games元素的属性。

使用回音或var_dump显示变量的内容,例如$notes$numberof我认为您会发现它们不包含您期望的内容。

答案 3 :(得分:0)

在$ value中,您保留Games节点的引用,该节点仅包含一个nameof节点。然后你做

foreach($nameof as $value2)

将执行一次,因为其中只有一个名称的节点。你的$ i将保持1,所以只打出第一场比赛。

您需要做的是选择所有“nX”节点并迭代它们但不通过节点名称,因为它们只是其中之一。或者,您可以更改for循环,以便完全按照numberof中的内容进行迭代。

答案 4 :(得分:0)

似乎您的问题是遍历<nameof>标记中的所有子元素。

尝试以下方法:

foreach($nameof as $node){
    foreach($node->childNodes as $child) {
       echo '<br/>Node Name: '.$child->nodeName.' Node Value: '.$child->nodeValue.'<br/>';
    }
}

而不是上一个foreach语句并观察输出

答案 5 :(得分:0)

您的第二个foreach错误,因为它仅在nameof中当前为一个条目的Games条目后进行评估。

您需要使用nameof_来迭代您的案例:

$objDOM = new DOMDocument(); 
$objDOM->load("content.xml");
$note = $objDOM->getElementsByTagName("Games"); 

foreach( $note as $value ) 
{ 
    $numberof = $value->getElementsByTagName("numberof"); 
    $numberof_  = $numberof->item(0)->nodeValue; 
    echo($numberof_." games found!<br />\n");

    $numberof = (integer)$numberof_;
    $nameof = $value->getElementsByTagName("nameof");
    for ($i = 1; $i <= $numberof_; $i++)
    {
        $n = (string)$i;
        $nameof_[$i] = $nameof->item(0)->getElementsByTagName("n".$n);
        $nameof_[$i] = $nameof_[$i]->item(0)->nodeValue;
        echo(((string)$i).": ".$nameof_[$i]."<br />\n");
    }
} 

作为一个建议,仔细看看你的数据定义 - 就像@jon_darkstar所建议的那样 - 它看起来并不是非常简单(例如,易于自动解析)。

例如,如果您使用此格式,解析将更容易:

<?xml version="1.0" encoding="utf-8"?>
<contentdata>
  <Games>
    <item name="Game1" />
    <item name="Game2" />
  </Games>
  <Software>
    <item name="Software1" />
  </Software>
</contentdata>

您可以使用

解析
$objDOM = new DOMDocument();
$objDOM->load("content.xml");
$gamesElements = $objDOM->getElementsByTagName("Games");

foreach ($gamesElements as $gamesElement)
{
    $itemElements = $gamesElement->getElementsByTagName("item");
    echo ($itemElements->length . " games found!<br />\n");

    $i = 1;
    foreach ($itemElements as $itemElement) {
       $name = $itemElement->attributes->getNamedItem('name')->nodeValue;
       echo("$i: $name<br />\n");
       $i++;
    }
}
相关问题