XML解析 - 缺失节点

3
我遇到了一个问题,我的xml文件的一些节点被解析并正确显示,而其他节点则没有被检测到(至少我不知道出了什么问题)。
与其发布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 />";

        }
    }
}

使用该代码,我可以获取每个元素oname。但是我还需要获取存储在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个回答

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

非常感谢您给我提供的解决方案,现在我已经可以专注于下一步了!再次感谢! - SubZero

1

请查看文档以获取可以在DOMNode中访问的属性的完整列表。关于您的问题:

  1. 检查$tempattributes属性,以访问其所有属性。它是一个DOMNamedNodeMap,因此您可以像这样访问它们:

    foreach ($temp->attributes as $name => $attrNode) {
        echo $name."=".$attrNode."<br />";
    }
    
  2. 在将其包含在结果中之前,可以通过将nodeTypeXML_ELEMENT_NODE进行比较来消除不需要的Text节点。


1
对于这样的XML文档,最好使用SimpleXML进行处理。通常你需要查找的是所谓的属性。除了元素的子文本值之外,元素还具有属性

SimpleXML中,访问相当简单:通过数组表示法和字符串键访问元素属性

$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>
...

演示


非常感谢!你向我展示了一种更高级/有组织的处理xml输入的方式!现在我只需要想办法将2个答案都标记为正确的即可! :) - SubZero

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接