2016-12-22 6 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-элементы таблицы форматируются с использованием той же структуры 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 

Проблема в том, что каждый раз мой объект возвращается обратно. Я также попытался использовать 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/en-us/library/aa468547.aspx) –

+0

@LoganReed Веб-сайт уже полностью сформирован и работоспособен и содержит все закрывающие теги, возможно, это была ошибка копирования. Я посмотрю на эту ссылку и посмотрю, поможет ли это. –

+0

Попробуйте сначала с очень маленьким хорошо сформированным XML-примером, а затем продолжите его, пока не найдете ошибку. –

ответ

0

Если вы пытаетесь получить все тексты («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. Ваша строка ввода слишком велика для msxml2 vba. Когда-то это случилось со мной, когда данные xfdf из adobe превысили некоторую максимальную длину строки, что привело к неправильному формированию ввода. Когда я запускал XSL вне vba или удалял поле длинными строками, он работал.
  3. Существует разница между тем, как обрабатываются XML и HTML. Я не знаком с HTML, поэтому не могу слишком много комментировать эту часть вашего кода.
+0

Я проверяю номер 2. Там дерьмо тонна, и я имею в виду, что из пробела в html. Это выглядит ужасно в источнике. –

Смежные вопросы