【问题标题】:firstChild determined weirdly in XML DOM tree在 XML DOM 树中奇怪地确定了 firstChild
【发布时间】:2017-01-25 00:34:47
【问题描述】:

谁能告诉我为什么下面的第一行可以工作,而其他 4 行不行?
对于以下 5 行中的每一行...

1.) 右边----我写下了发生的事情。
2.)在下面——我写了我期望发生的事情。

PHP

$doc = new DOMDocument();
$doc->load($str);
$doc->preserveWhiteSpace = true;
$doc->formatOutput = true;


/*1*/ echo $doc->firstChild->nodeValue;  //WORKED - Echoed the whole DOC
          //doc-> comments  
/*2*/ echo $doc->firstChild->firstChild->nodeValue;  //DIDNT WORK
          //doc-> comments ->   post            
/*3*/ echo $doc->firstChild->firstChild->textContent; //DIDNT WORK
          //doc-> comments ->   post        
/*4*/ echo $doc->firstChild->firstChild->nextSibling->nodeValue; //Echoed whole 1st <post>
          //doc-> comments ->   post   -> 2nd post          
/*5*/ echo $doc->firstChild->firstChild->nextSibling->firstChild->nodeValue; //Echoed 1st <post>'s <id>("1").
          //doc-> comments ->   post   -> 2nd post ->  id ("2")     

XML

<?xml version="1.0"?>
<comments>
    <post>
        <id>1</id><author>Demetrius</author>
    </post>
    <post>
        <id>2</id><author>Demetrius</author>
    </post>
</comments>

我能想出的唯一解释是我有“抵消错误”,所以 (在树的各个级别)...

2.) firstChild 确实是&lt;?xml version="1.0"?&gt; 标签,并且

3.) firstChild 充当nextSibling 然后

4.) nextSibling 充当firstChild

但这没有任何意义。

【问题讨论】:

    标签: php xml dom


    【解决方案1】:

    如您的回答中所述,firstChild 获取文本节点以及元素节点。

    更具体地说,当解析器被赋予以下内容时:

    <comments>
        <post>
    

    ...&lt;comments&gt; 之后的换行符和&lt;post&gt; 之前的四个空格导致解析器创建一个文本节点,并使该文本节点成为comments 元素的第一个子节点。

    因此,如果您使用 DomDocument.load 并且只想要元素节点,那么您需要:

    1. 使用DOMNode.childNodes 并遍历其返回的节点列表。
    2. 对于DOMNode.childNodes 节点列表中的每个节点,使用DOMNode.nodeType 检查type of each node
    3. 如果节点类型为XML_TEXT_NODE,则跳过。如果是XML_ELEMENT_NODE,那就做点什么吧。

    或者,您可以使用SimpleXML,它提供了一个更方便的 API 让您可以这样做,例如:

    $comments = new SimpleXMLElement($str);
    echo $comments->post[0]->id;
    echo $comments->post[0]->author;
    

    【讨论】:

    • 哇。我刚刚弄清楚了var_dump() 在 PHP 中的用处,以确定您可以获取或检查哪些属性(例如,nodeType,正如您所说)。这完全消除了我所处的麻痹迷雾。无论如何,感谢您在您的帖子中为我拼写出来!
    【解决方案2】:

    当我在&lt;comments&gt; 之后但在第一个&lt;post&gt; 之前键入“MMM”时,/*2*//*3*/ 行都回显MMM 而不是(和以前一样)什么都没有。所以显然根节点的第一个孩子是它自己的文本内容。 (然后,nextSibling 给了我根的第一个子元素-元素,即&lt;post&gt;。)

    【讨论】:

      猜你喜欢
      • 2010-12-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多