как пройти через объект DOM? - PullRequest
0 голосов
/ 30 ноября 2011

Мне нужно пройти через объект DOM и отобразить текст в нем без дубликатов.

Пример:

<div>
      <div>hello
      <div>welcome</div>
      hai
     </div>
123
</div>

Выход должен быть

hello
welcome
hai
123

Как реализовать это в VBScript?

На самом деле я пытался с рекурсией, но, похоже, она работает неправильно.

function traverse(allnode)

for each node in allnode
  if node.hasChildNodes then
      traverse(node.childNodes)
  else
      Msgbox node.nodeValue
  end if
end function

Эта функция печатает «текст» более одного раза (то есть для каждого элемента div). Как реализовать это в VBScript?

1 Ответ

0 голосов
/ 30 ноября 2011

Учитывая этот HTML:

<html>
 <body>
  <div>
   <div>
    hello
    <div>welcome</div>
    hai
   </div>
   123
  </div>
  <p>noli me tangere</p>
 </body>
</html>

в oDOM и вызов этого Sub

Sub traverseDom00(ndX, nInd)
  WScript.Echo Space(nInd), ndX.nodeName
  If ndX.hasChildNodes Then
     Dim ndY
     For Each ndY In ndX.childNodes
         traverseDom00 ndY, nInd + 1
     Next
  End If
  WScript.Echo Space(nInd), "/" & ndX.nodeName
End Sub

через traverseDom00 oDOM, 0 приводит к

 #document
  HTML
   HEAD
    TITLE
    /TITLE
   /HEAD
   BODY
    DIV
     DIV
      #text
      /#text
      DIV
       #text
       /#text
      /DIV
      #text
      /#text
     /DIV
     #text
     /#text
    /DIV
    P
     #text
     /#text
    /P
   /BODY
  /HTML
 /#document

Этот Sub показывает базовую структуру для рекурсивного обхода DOM. Если вы сравните это с вашей функцией (почему функция?), Вы увидите, что

  1. вам не хватает следующего
  2. Вы должны проверить наличие дочерних узлов до зацикливания

На основе структуры кода обхода легко придумать

Sub traverseDom01(ndX, aRes)
  If ndX.hasChildNodes Then
     Dim ndY
     For Each ndY In ndX.childNodes
         traverseDom01 ndY, aRes
     Next
  End If
  If "#text" = ndX.nodeName Then
     If "DIV" = ndX.parentNode.nodeName Then
        ReDim Preserve aRes(UBound(aRes) + 1)
        aRes(UBound(aRes)) = Trim(ndX.nodeValue)
     End If
  End If
End Sub

для сбора текстов, которые являются детьми DIV. Вызывается через

  Dim aDTs : aDTs = Array()
  traverseDom01 oDOM, aDTs
  WScript.Echo "|" & Join(aDTs, "|") & "|"

результат

|hello|welcome|hai|123|
...