【发布时间】:2015-06-23 19:47:35
【问题描述】:
我的程序扫描一个名为“Ralls, Kim”的作者,并打印出作者姓名、书籍类型、书名和商店位置。我现在要做的是设置检查:如果版本等于 13,则不应打印 StoreLocation 但仍会打印所有其他项目。
需要注意的另一点是 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')"
感谢任何有用的 cmets,因为我渴望学习!谢谢。
样本输出:
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
【问题讨论】:
标签: xml vba dom xpath xml-parsing