【问题标题】:Only the first element is being read while processing XML in PHP在 PHP 中处理 XML 时只读取第一个元素
【发布时间】:2011-03-10 09:54:28
【问题描述】:

我在用 PHP 读取 XML 文件时遇到了一些问题。我对PHP不是很熟练,所以我使用这个代码sn-p: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:游戏1
2:游戏2

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

我的代码有什么问题?如何解决?

【问题讨论】:

  • 为什么不把代码贴在这里?
  • 我试过了,但它给出了一些奇怪的格式结果。

标签: php xml


【解决方案1】:

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

使用简单的 XML:

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

【讨论】:

【解决方案2】:

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

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

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

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

使用 echoes 或 var_dump 显示变量的内容,如 $notes$numberof 我想你会发现它们不包含你所期望的。

【讨论】:

    【解决方案3】:

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

    foreach($nameof as $value2)
    

    将只执行一次,因为其中只有一个 nameof 节点。您的 $i 将保持为 1,因此只会打印出第一个游戏。

    您需要做的是选择所有“nX”节点并遍历它们,而不是通过 nameof 节点,因为只有其中一个。或者,您可以更改 for 循环,以便您迭代的次数与 numberof 中所写的一样多。

    【讨论】:

      【解决方案4】:

      您的问题似乎是遍历 &lt;nameof&gt; 标记中的所有子元素。

      尝试以下方法:

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

      而不是你最后的foreach 语句并观察输出

      【讨论】:

        【解决方案5】:

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

        您需要使用您的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(例如,易于自动解析)。

        如果你例如使用这种格式,解析会更容易:

        <?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++;
            }
        }
        

        【讨论】:

          【解决方案6】:

          查看 SimpleXML 函数:simplexml_load_string

          【讨论】:

            猜你喜欢
            • 2016-12-05
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-10-11
            • 1970-01-01
            相关资源
            最近更新 更多