簡體   English   中英

為什么DomDocument getElementsByTagName會返回一半NodeList?

[英]Why DomDocument getElementsByTagName give back an half NodeList?

我使用DomDocument生成一些非標准標記HTML,結果如下:

/* Input HTML
  <div id="toobar_top">
    <widget id="flag_holder"></widget>
    <widget id="horizontal_menu"></widget>
  </div>
  <div id="header">
    <widget name="header"></widget>
  </div>
*/

我想要做的是用一些有用的東西“翻譯”每個小部件......它們是帶有參數的簡單占位符。

該類的函數提取是:

private function widgeter($doc) { //Give it an DomDocument HTML containing <widget> elements and will translate them into usable stuff
    $this->_widgetList = $doc->getElementsByTagName($this->_widgetTransformTo);
    foreach ($this->_widgetList as $widget) {
        $data = array();
        if ($widget->hasAttributes()) {
        foreach ($widget->attributes as $attribute) {
            $data[][$attribute->name] = $attribute->value;
            // @TODO: Implements Widget Transformation

        }
        }
        // Next 2 lines are just for debug
        $string = serialize($data);
        $newWidget = $doc->createElement('p', $string);
        $widget->parentNode->replaceChild($newWidget, $widget);
    }
    return $doc;
    }

然后,當我保存HTML()$ doc時,我看到:

/* Output HTML
  <div id="toobar_top">
    <p>[{"id":"flag_holder"}]</p>
    <widget id="horizontal_menu"></widget>
  </div>
  <div id="header">
    <p>[{"id":"header"}]</p>
  </div>
*/

為什么“horizo​​ntal_menu”沒有被翻譯?

小部件的位置並不重要(我嘗試只使用一個包含所有小部件的div,每個小部件使用div)。

我弄不清楚......

之所以發生這種情況,是因為您在循環它們的同時替換DOMNodeList中的元素。 DOMNodeList不是數組 ,因此foreach 不對副本進行操作 ,而是對對象本身進行操作。

基本上,我認為正在發生的事情是:

  • 您替換<widget>的第一個實例(項目0)。
  • 指針前進到下一個項目(項目1)。
  • 項目0已被替換,不再存在。
  • 發生項目轉移:項目1變為項目0,項目2變為項目1。
  • 指針仍指向第1項(最初為第2項,有效地跳過節點)。

您需要做的是將元素保存在數組中然后更改它們,而不是在DOMNodeList上循環:

$this->_widgetList = array();
foreach ($domNodeList as $node) {
   $this->_widgetList[] = $node;    
}

foreach ($this->_widgetList as $widget) {
   // do stuff
}

為避免兩次迭代,您可以解析反向的元素列表

$widgets = $doc->getElementsByTagName( 'widget' ); // get all elements

for( $i = $widget->length; $i > 0; $i-- ){
    $widget = $doc->getElementsByTagName( 'widget' )->item( $i - 1 );

    // do stuff whith the widget
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM