2016-12-22 7 views
0

Ich versuche, Code zu schreiben, die durch diese DOM-Struktur sichten werden:Parsing DOM unter Verwendung von XML (VBA)

<html> 
<head> 
    <body> 
    <table id="the-table" border="1"> 
    <thead> 
    <tbody> 
    <tr> </tr> 
    <tr> 
     <td class="x-grid3-hd-inner" bgcolor="#8dd5e7" colspan="7"> 
    </tr> 
    <tr> 
     <td class="x-grid3-hd-inner" bgcolor="#8dd5e7" colspan="7"> 
    </tr> 
    <tr> 
    <tr> 
     <td class="oneline">2</td> 
     <td class="oneline">ENB</td> 
     <td class="oneline">2</td> 
     <td class="oneline">CELL_99</td> 
     <td class="oneline">255.255.255.0</td> 
     <td class="oneline">My Group</td> 
     <td class="oneline">*</td> 
    </tr> 
    <tr> 
    <tr> 
    <tr> 
    ... 
    <tr> 
    <tr> 
    </tbody> 
    </table> 
</body> 
</html> 

Ich versuche, den Text an jedem td Elemente für alle tr Elemente der Tabelle zu extrahieren. Ich habe ein Beispiel oben ausgedehnt. Alle td-Elemente der Tabelle werden mit der gleichen HTML-Struktur (neben dem Titel der Tabelle) formatiert. Dies ist die Methode, die ich bisher benutzt habe.

Sub ParseWebPage(url As String, sheet As String, searchCrit As String) 
    Dim objXML As MSXML2.DOMDocument 
    Set objXML = New MSXML2.DOMDocument 
    Set htm = CreateObject("htmlFile") 
    With CreateObject("msxml2.xmlhttp") 
     .Open "GET", url, False 
     .send 
     xmlresp = .responseText 
    End With 
    objXML.loadXML (xmlresp) 
    Dim objElem As MSXML2.IXMLDOMElement 
    Debug.Print xmlresp 

    objXML.loadXML (xmlresp) 
    Set objElem = objXML.selectSingleNode("tr") 
    Debug.Print "Found" & objElem.text 
End Sub 

Das Problem ist, jedes Mal, wenn mein ObjElem leer zurückkehrt. Ich habe auch versucht, eine NodeList anstelle von IXMLDOMElement zu verwenden, aber es wurde immer leer zurückgegeben.

Ich glaube, das Problem, das String-Argument. Ich habe versucht mit "tr", "oneline", "/ html/body/table/tbody", und erstellen Sie eine Schleife für jeden "/ html/body/table/tbody/tr [x]/td [y]" aber keiner von diesen war effektiv.

Kann mir hier jemand helfen?

+0

kommentieren Ihre allgemeine Vorgehensweise ist richtig. Ich denke, das Problem ist nicht wohlgeformtes XML (welches HTML aus dem Internet oft ist). Ich sehe viele '' Tags, aber fast keine' 'schließenden Tags. MSXML erwartet perfektes XML, also sollten leere ' 'sein. Überprüfen Sie auch 'objXML' mit' If objXML Is Nothing Then ... '- weil Sie keine XML-Parse-Fehler abfangen. Wenn es nichts ist - dann gab es einen Fehler beim Parsen. Sehen Sie sich diese Anleitung an, um es richtig zu machen [Ein Anfängerhandbuch für das XML-DOM] (https://msdn.microsoft.com/en-us/library/aa468547.aspx) –

+0

@LoganReed Die Website ist bereits vollständig erstellt und betriebsbereit und enthält alle schließenden Tags, es ist möglicherweise ein Kopierfehler aufgetreten. Ich werde auf diesen Link schauen und sehen, ob das hilft. –

+0

Versuchen Sie zuerst mit einem sehr kleinen wohlgeformten XML-Beispiel und erweitern Sie es dann weiter, bis Sie den Fehler dann finden. –

Antwort

0

Wenn Sie versuchen, alle Texte ("2", "ENB" etc.) in den Elementen der td zu bekommen, versuchen Sie folgendes:

Dim objList As MSXML2.IXMLDOMNodeList 
Set objList = objXML.SelectNodes("//tr/td") 
For i = 0 To objList.Length - 1 
    Debug.Print objList.Item(i) 
Next i 

Hoffnung, das funktioniert. Hatte keine Zeit zu testen, aber kopiert von ähnlichen Arbeitscode ich habe.

+0

Die Liste der Knoten ist noch leer. Es scheint, als ob selectNodes/selectSingleNode nur für xml verwendet wird. Ich versuche nun, es auf einen kleineren Testfall zu reduzieren. –

0
Sub ParseWebPage(url As String, sheet As String, searchCrit As String) 
Dim objXML As MSXML2.DOMDocument 
Set objXML = New MSXML2.DOMDocument 
Set htm = CreateObject("htmlFile") 
Dim tableData() As String 
Dim openPos, closePos As Integer 
Dim midPart As String 

With CreateObject("msxml2.xmlhttp") 
    .Open "GET", url, False 
    .send 
    xmlresp = .responseText 
End With 
objXML.loadXML (xmlresp) 
tableData = Split(xmlresp, searchCrit) 

For i = 12 To UBound(tableData) - 1 
    openPos = InStr(tableData(i), Chr(34) & ">") 
    closePos = InStr(tableData(i), "</td>") 
    midPart = mid(tableData(i), openPos + 2, closePos - openPos - 2) 
    Debug.Print midPart 
Next i 
End Sub 

Dies ist eine oke Lösung für jetzt. Aber ich werde weiterhin mehr zu diesem Thema recherchieren. Ich habe die XML-Bibliotheken überhaupt nicht benutzt.

1
Sub test() 
    Dim objList As MSXML2.IXMLDOMNodeList 
    Dim objxml As New MSXML2.DOMDocument 
    Dim i As Integer 

    objxml.Load ("C:\test.xml") 'used load, loadXML would be correct for your use 
    Set objList = objxml.SelectNodes("//tr/td") 
    For i = 0 To objList.Length - 1 
     Debug.Print objList.Item(i).Text 
    Next i 
End Sub 

den obigen Code auf die folgenden verwendet:

<html> 
<head> 
    <body> 
    <table id="the-table" border="1"> 
    <thead> 
    <tbody> 
     <tr> 
     <td class="oneline">2</td> 
     <td class="oneline">ENB</td> 
     <td class="oneline">2</td> 
     <td class="oneline">CELL_99</td> 
     <td class="oneline">255.255.255.0</td> 
     <td class="oneline">My Group</td> 
     <td class="oneline">*</td> 
    </tr> 
    </tbody> 
    </thead> 
    </table> 
</body> 
</head> 
</html> 

Hatte die Eingabedatei als XML gespeichert. Ich habe daraus die gewünschten Ergebnisse. Das lässt mich glauben, dass einer der folgenden Fälle passiert:

  1. Ihre frühere xmlresp ist nicht gut gebildet. Können Sie es überprüfen oder objxml exportieren, um zu sehen, ob es korrekt gebildet wurde?
  2. Ihre Eingabezeichenfolge ist zu groß für VBA's msxml2. Ich hatte das einmal mit mir passiert, wo xfdf-Daten von Adobe über eine maximale Stringlänge hinausgingen, was dazu führte, dass der Eingang nicht richtig gebildet wurde. Wenn ich ein XSL außerhalb von VBA laufen ließ oder das Feld mit den langen Strings entfernte, funktionierte es.
  3. Es gibt einen Unterschied zwischen der Behandlung von XML und HTML. Ich bin nicht so vertraut mit HTML, kann also nicht zu diesem Teil Ihres Codes zu viel
+0

Ich überprüfe Nummer 2. Es gibt einen Mist, und ich meine, dass von Leerzeichen in der HTML. Es sieht schrecklich in der Quelle aus. –