【问题标题】:PHP DOM: rather newbie questionPHP DOM:相当新手的问题
【发布时间】:2010-09-16 15:33:17
【问题描述】:

我刚刚开始用 PHP 修改 XML 操作,但我偶然发现了一些意想不到的东西。这是我用作测试输入的 XML:

<list>
    <activity1> running </activity1>
    <activity2> swimming </activity2>
    <activity3> soccer </activity3>
</list>

现在,我期待这个 PHP 代码会输出 'activity1':

$xmldoc = new DOMDocument();
$xmldoc->load('file.xml');

//the line below would make $root the <list> node
$root = $xmldoc->firstChild;

//the line below would make $cnode the first child 
//of the <list> node, which is <activity1>
$cnode = $root->firstChild;

//this should output 'activity1'
echo 'element name: ' . $cnode->nodeName;

相反,此代码输出#text。在打印节点名称之前,我可以通过在代码中插入新行来解决这个问题:

$cnode = $cnode->nextSibling;

现在,我本来希望打印“activity2”,但正在打印“activity1”。怎么回事?

【问题讨论】:

    标签: php xml dom


    【解决方案1】:

    第一个node是开始列表标签和activity1标签之间的文本(在本例中是空格),下一个node是activity1 元素时间>。元素与节点不同。

    【讨论】:

      【解决方案2】:

      要获得您期望的行为,您需要传入 LIBXML_NOBLANKS 作为 load() 调用的第二个参数

      <?php
      $xmldoc = new DOMDocument();
      $xmldoc->load('file.xml', LIBXML_NOBLANKS);
      ?>
      

      【讨论】:

        【解决方案3】:

        关于 Czimi 答案的注释:删除仅空白节点不会阻止您检查节点的类型(无论它是元素、文本节点、评论......)。一般来说,如果您只对选择元素节点感兴趣,您需要执行以下操作:

        while($nodeInQuestion->nodeType != 1 && $nodeInQuestion->nextSibling) {
            $nodeInQuestion = $nodeInQuestion->nextSibling;
        }
        

        这是一种伪代码。显然,如果您正在寻找一个元素并在找到它之前到达 parentNode 的 childNodes 的末尾,那么您需要以某种方式处理失败。

        【讨论】:

          【解决方案4】:

          如果您使用 XPath 来查询您的文档,则无需担心这种奥秘。使用DOMDocument::xpath_eval() 来评估模式/list/*,无论如何,您将得到的只是顶级list 元素的子元素。

          【讨论】:

            猜你喜欢
            • 2011-08-08
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2010-12-22
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多