2016-12-22 145 views
0

我想編寫的代碼,將通過這個DOM結構篩選:解析DOM使用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> 

我試圖提取每個TD元素的文本表的所有TR元素。我在上面擴展了一個例子。表格的所有td元素都使用相同的html結構格式化(除了表格的標題)。這是迄今爲止使用的方法。

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 

問題是,每當我的objElem返回空。我也嘗試使用NodeList而不是IXMLDOMElement,但它總是返回空。

我認爲問題是字符串參數。我曾嘗試使用「tr」,「oneline」,「/ html/body/table/tbody」,併爲每個「/ html/body/table/tbody/tr [x]/td [y]」創建循環,但是這些都沒有效果。

有人可以幫我嗎?

+0

您的一般方法是正確的。我認爲這個問題是非格式良好的XML(通常來自網絡的HTML)。我看到很多''標籤,但幾乎沒有''結束標籤。 MSXML期望完美的XML,所以空的應該是''。還檢查'objXML'與'If objXML Is Nothing Then ...' - 因爲你沒有捕獲XML解析錯誤。如果它不是 - 那麼在解析時出現錯誤。請查看本指南,瞭解如何正確使用[XML DOM初學者指南](https://msdn.microsoft.com/zh-cn/library/aa468547.aspx) –

+0

@LoganReed該網站已經完全形成並可操作幷包含所有結束標記,這可能是發生的複製錯誤。我會看看這個鏈接,看看是否有幫助。 –

+0

首先嚐試使用非常小的格式良好的XML示例,然後繼續擴展,直到找到錯誤。 –

回答

0

如果你試圖讓所有在TD元素的文本(「2」,「ENB」等),請嘗試以下操作:

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 

希望工程。沒有時間測試,但是從我的類似工作代碼複製而來。

+0

節點列表仍爲空。看起來像使用selectNodes/selectSingleNode僅用於xml ..我現在試圖將其降低到更小的測試用例。 –

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 

這是現在好的解決方案。但是,我會繼續對這個話題做更多的研究。我最終沒有使用XML庫。

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 

用在按照上述代碼:

<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> 

假如保存爲.XML輸入文件。我從中得到了預期的結果。這讓我相信,下面的一個正在發生:

  1. 你剛纔xmlresp沒有很好地形成。你可以檢查它或導出objxml,看它是否正確形成?
  2. 您的輸入字符串對於vba的msxml2來說太大。我曾經遇到過這種情況,其中來自Adobe的xfdf數據超過了導致輸入未正確形成的最大字符串長度。當我在vba之外運行XSL或使用長字符串刪除字段時,它工作正常。
  3. XML和HTML的處理方式有所不同。我對HTML並不熟悉,所以不能對代碼的那部分進行太多評論
+0

我檢查數字2.有一個垃圾噸,我的意思是,在html中的空白。來源看起來很糟糕。 –