XML解析 - 缺少节点

时间:2013-03-08 15:01:31

标签: php xml parsing dom

我遇到的问题是我的xml文件的某些节点已被解析&正确显示而其他人未被检测到(至少我不知道这里出了什么问题)

我将提供link to it,而不是发布xml文件。这是一个小的XML片段,供您查看xml结构:

<offers version="1"><group name="games">
    <o id="1" url="http://inexus.us/world-of-warcraft-eu/pre-paid-game-time-card-60-days" price="21.53" avail="1">
        <name>World of Warcraft EU Pre-Paid Game Time Card 60 Days</name>
        <currency>
            EUR
        </currency>
    </o>

现在,我正在使用此代码来解析/读取xml文件。

$xmlDOM = new DOMDocument();
$xmlDOM->load("http://inexus.us/compare.xml");
$document = $xmlDOM->documentElement;
foreach ($document->childNodes as $node) {
    if ($node->hasChildNodes()) {
        foreach($node->childNodes as $temp) {
            echo $temp->nodeName."=".$temp->nodeValue."<br />";

        }
    }
}

使用该代码我得到每个elemet的name o 但是我还需要将信息存储在o元素中......(即idurlprice)但我不太明白我怎么做访问它们。

此外,输出还会返回多个#text=块。 (我猜这是因为xml中的空格?)

输出的一小部分:

#text=
#text=
o= World of Warcraft EU Pre-Paid Game Time Card 60 Days EUR
#text=
o= World of Warcraft EU Battle Chest cd-key EUR
#text=
o= World of Warcraft EU Cataclysm cd-key EUR
#text= 

感谢任何帮助/提示!

3 个答案:

答案 0 :(得分:2)

#text必须处理空白。您可以使用preserveWhiteSpace = false(见下文),但必须记住在load()之前使用此功能。

对于属性,您可以使用hasAttributes()检查节点是否具有属性,然后使用attributes迭代节点的属性。

在下面的示例中,我选择了一个快捷方式并抓取了所有o标记:

<?php
$xmlDOM = new DOMDocument();
$xmlDOM->preserveWhiteSpace = false;
$xmlDOM->load("http://inexus.us/compare.xml");
$offers = $xmlDOM->getElementsByTagName('o');
foreach ($offers as $offer) {
    if($offer->hasAttributes()){
        foreach($offer->attributes as $attr){
            $name = $attr->nodeName;
            $value = $attr->nodeValue;
            echo $name.' = '.$value.'<br>';
        }
    }
    if ($offer->hasChildNodes()) {

        foreach($offer->childNodes as $o) {
            echo $o->nodeName."=".$o->nodeValue."<br />";

        }
    }
    echo '<hr>';
}?>

答案 1 :(得分:1)

点击the docs查看您可以在DOMNode中访问的完整属性列表。对于你的问题:

  1. 检查$temp的{​​{3}}属性,以便能够访问其所有属性。它是attributes,因此您可以访问它们(例如):

    foreach ($temp->attributes as $name => $attrNode) {
        echo $name."=".$attrNode."<br />";
    }
    
  2. 您可以先对DOMNamedNodeMap nodeType进行测试,然后再将XML_ELEMENT_NODE包含在结果中,以消除不需要的Text个节点。

答案 2 :(得分:1)

对于这样的XML文档,在SimpleXML中处理它通常更容易。通常,您正在寻找的是属性。在作为元素的子元素的 text 值旁边,元素也具有属性

SimpleXML 中,访问非常简单:访问元素属性是使用数组表示法和字符串键:< / p>

$game['id']; # id attribute of $game (here the <o> element)

要访问孩子(通常只有一个孩子,例如<name>),您可以通过它的子元素名称访问它:

$game->name; # (first) name child element of $game

如果你在字符串上下文中使用它(例如作为字符串参数; echo或者铸造(string) $game->name),它将不返回元素,而是返回内部文本值。

以下是一些示例代码(也使用简单的xpath):

$url = 'http://inexus.us/compare.xml';
$xml = simplexml_load_file($url);

foreach($xml->xpath('/*/group/o') as $index => $game)
{
    printf("[%04d] %' -48s  %' 5s %s\n       <%s>\n",
        $game['id'],            # id attribute
        trim($game->name),      # name child text value
        $game['price'],         # price attribute
        trim($game->currency),  # currency child text value
        $game['url']            # url attribute
    );
}

这是输出:

[0001] World of Warcraft EU Pre-Paid Game Time Card 60 Days  21.43 EUR
       <http://inexus.us/world-of-warcraft-eu/pre-paid-game-time-card-60-days>
[0003] World of Warcraft EU Battle Chest cd-key          10.31 EUR
       <http://inexus.us/world-of-warcraft-eu/battle-chest-cd-key>
[0668] World of Warcraft EU Cataclysm cd-key              6.18 EUR
       <http://inexus.us/world-of-warcraft-eu/cataclysm-cd-key>
[0954] World of Warcraft EU Mists of Pandaria cd-key     18.80 EUR
       <http://inexus.us/world-of-warcraft-eu/mists-of-pandaria-cd-key>
[0988] World of Warcraft EU Battle Chest + Cataclysm cd-key  15.48 EUR
       <http://inexus.us/world-of-warcraft-eu/battle-chest-cataclysm-cd-key>
[0018] Eve Online Pre-Paid Card 60 Days Special Edition  28.40 EUR
       <http://inexus.us/eve-online/pre-paid-card-60-days-special-edition>
[0766] Eve Online +30 Days cd-key                        11.60 EUR
       <http://inexus.us/eve-online/30-days-cd-key>
[1057] Eve Online Pre-Paid Card 60 Days                  25.82 EUR
       <http://inexus.us/eve-online/pre-paid-card-60-days>
[0029] Sony Online Pre-Paid 30 days EU                   14.19 EUR
       <http://inexus.us/sony-online/pre-paid-30-days-eu>
...

Demo