VBA DOM XML 属性检查语句

VBA DOM XML Attribute Check Statement

我的程序扫描名为 "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')"

感谢任何有用的评论,因为我渴望学习!谢谢。

示例输出:

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

关于第一个问题,您可以获取版本号并使用简单的if else 来更改StoreLocation 值。像这样:

BookVersion = pn.getAttribute("version")

......

If BookVersion = "13" Then
    StoreLocation = ""
Else
    StoreLocation = loc.Text
End If

关于问题 2,您的 xpath 在 xpath 1.0 中无效。试试这种方式:

Set loc = pn.SelectSingleNode("misc/PublishedAuthor/*[contains(name(),'StoreLocation')]")

除上述内容外,您还需要明确说明要用于 XMLFile 的选择语言是 xpath :

.....
Set XMLFile = CreateObject("Microsoft.XMLDOM")
XMLFile.Load ("C:\Books.xml")
XMLFile.setProperty "SelectionLanguage", "XPath"
.....