我的程序掃描名爲「Ralls,Kim」的作者並打印作者姓名,書籍類型,書名和StoreLocation。我現在要做的是設置一個檢查:如果版本等於13,那麼StoreLocation不應該被打印出來,但它仍然會打印所有其他項目。VBA DOM XML屬性檢查語句
另一項需要注意的是StoreLocation和StoreLocations都包含相同的變量。我無法成功使用XPath來比較這些(Set loc = pn.SelectSingleNode("misc/PublishedAuthor/contains(name(),'StoreLocation')"
)不斷給我的錯誤),所以我最終只使用了一個可恥的if/else語句。
Sub mySub()
Dim XMLFile As Variant
Dim Author As Variant
Dim athr As String, BookType As String, Title As String, StoreLocation As String
Dim AuthorArray() As String, BookTypeArray() As String, TitleArray() As String, StoreLocationArray() As String
Dim i As Long, x As Long, j As Long, pn As Object, loc As Object, arr, ln As String, loc2 As Object
Dim mainWorkBook As Workbook
Dim n As IXMLDOMNode
Set mainWorkBook = ActiveWorkbook
Set XMLFile = CreateObject("Microsoft.XMLDOM")
XMLFile.Load ("C:\Books.xml")
x = 1
j = 0
Set Author = XMLFile.SelectNodes("/catalog/book/author")
For i = 0 To (Author.Length - 1)
athr = Author(i).Text
If athr = "Ralls, Kim" Then
Set pn = Author(i).ParentNode
BookType = pn.getAttribute("id")
Title = pn.getElementsByTagName("title").Item(0).nodeTypedValue
Set loc = pn.SelectSingleNode("misc/PublishedAuthor[@id='" & athr & "']/StoreLocation")
'not found on full name - try last name
If loc Is Nothing Then
'get the last name
arr = Split(athr, ",")
ln = Trim(arr(LBound(arr)))
Set loc = pn.SelectSingleNode("misc/PublishedAuthor[@id='" & ln & "']/StoreLocation")
End If
If Not loc Is Nothing Then
StoreLocation = loc.Text
Else
Set loc2 = pn.SelectSingleNode("misc/PublishedAuthor[@id='" & ln & "']/StoreLocations")
StoreLocation = loc2.Text
End If
AddValue AuthorArray, athr
AddValue BookTypeArray, BookType
AddValue TitleArray, Title
AddValue StoreLocationArray, StoreLocation
j = j + 1
x = x + 1
End If
Next
Range("A3").Resize(j, 1).Value = WorksheetFunction.Transpose(AuthorArray)
Range("B3").Resize(j, 1).Value = WorksheetFunction.Transpose(BookTypeArray)
Range("C3").Resize(j, 1).Value = WorksheetFunction.Transpose(TitleArray)
Range("D3").Resize(j, 1).Value = WorksheetFunction.Transpose(StoreLocationArray)
End Sub
'Utility method - resize an array as needed, and add a new value
Sub AddValue(arr, v)
Dim i As Long
i = -1
On Error Resume Next
i = UBound(arr) + 1
On Error GoTo 0
If i = -1 Then i = 0
ReDim Preserve arr(0 To i)
arr(i) = v
End Sub
我的XML:
<?xml version="1.0"?>
<catalog>
<book id="Adventure" version="13">
<author>Ralls, Kim</author>
<title>XML Developer's Guide</title>
<price>44.95</price>
<misc>
<Publisher id="5691">
<PublisherLocation>Los Angeles</PublisherLocation>
</Publisher>
<PublishedAuthor id="Ralls">
<StoreLocation>N/A</StoreLocation>
</PublishedAuthor>
</misc>
</book>
<book id="Adventure" version="14">
<author>Ralls, Kim</author>
<title>Midnight Rain</title>
<price>5.95</price>
<misc>
<Publisher id="4787">
<PublisherLocation>New York</PublisherLocation>
</Publisher>
<PublishedAuthor id="Ralls">
<StoreLocations>Store B</StoreLocations>
</PublishedAuthor>
</misc>
</book>
<book id="Adventure" version="13">
<author>Ralls, Kim</author>
<title>Mist</title>
<price>15.95</price>
<misc>
<Publisher id="8101">
<PublisherLocation>New Mexico</PublisherLocation>
</Publisher>
<PublishedAuthor id="Ralls">
<StoreLocation>N/A</StoreLocation>
</PublishedAuthor>
</misc>
</book>
<book id="Mystery" version="14">
<author>Ralls, Kim</author>
<title>Some Mystery Book</title>
<price>9.95</price>
<misc>
<Publisher id="6642">
<PublisherLocation>New York</PublisherLocation>
</Publisher>
<PublishedAuthor id="Ralls">
<StoreLocation>Store D</StoreLocation>
</PublishedAuthor>
</misc>
</book>
</catalog>
總之
所以,如果有人可以請告知兩件事情:1。 我們應該在哪裏檢查,看看版本,把IF語句在最開始?如果該節點不存在,則會導致程序崩潰。 2.爲什麼我的XPath語句正確? Set loc = pn.SelectSingleNode("misc/PublishedAuthor/contains(name(),'StoreLocation')"
欣賞任何有用的評論,因爲我渴望學習!謝謝。
樣本輸出:
Ralls, Kim Adventure XML Developer's Guide Version 13 Not Compatible
Ralls, Kim Adventure Midnight Rain Store B
Ralls, Kim Adventure Mist Version 13 Not Compatible
Ralls, Kim Mystery Some Mystery Book Store D
感謝您的答覆。對於問題1,如果StoreLocation節點不存在並且版本節點會怎麼辦? – NRH
如果我們想在包含一個OR運算符的同時檢查作者姓名變量,會怎麼樣呢? 'Set loc = pn.SelectSingleNode(「misc/PublishedAuthor [@ id ='」&ln&「']/StoreLocation」|「misc/PublishedAuthor [@ id ='」&ln&「']/StoreLocations」)'Is對XPath參數的數量有限制,或者我們可以根據需要經常使用contains/starts-with()嗎? 'Set loc = pn.SelectSingleNode(「misc/PublishedAuthor [@ id ='」&ln&「']/* [starts-with(name(),'StoreLocation')]」)'對不起所有的問題,只是真的很好奇,併爲此着迷:) – NRH
@NRH都是有效的,應該工作(如果我理解你正確),並沒有限制xpath參數AFAIK的數量。爲了滿足你即將到來的關於xpath的好奇心,我建議在xpath工具(這是[其中之一](http://www.freeformatter.com/xpath-tester.html)或谷歌找到很多選擇和挑選你喜歡的人)。粘貼你的XML,然後嘗試任何你可以想到的xpath查詢,而不用麻煩,然後在VBA代碼中實際使用它。 – har07