【问题标题】:VBA DOM XML Attribute Check StatementVBA DOM XML 属性检查语句
【发布时间】: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


    【解决方案1】:

    关于第一个问题,你可以得到版本号并使用简单的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"
    .....
    

    【讨论】:

    • 感谢您的回复。对于问题1,如果StoreLocation节点不存在而version节点存在怎么办?
    • 如果我们想在检查作者姓名变量的同时包含一个 OR 运算符怎么办,这样的事情会起作用吗? Set loc = pn.SelectSingleNode("misc/PublishedAuthor[@id='" &amp; ln &amp; "']/StoreLocation" | "misc/PublishedAuthor[@id='" &amp; ln &amp; "']/StoreLocations") XPath 参数的数量是否有限制,或者我们可以根据需要经常使用 contains/starts-with() 吗? Set loc = pn.SelectSingleNode("misc/PublishedAuthor[@id='" &amp; ln &amp; "']/*[starts-with(name(),'StoreLocation')]") 抱歉所有问题,只是对此非常好奇和着迷:)
    • @NRH 都有效并且应该可以工作(如果我理解正确的话),并且对 xpath 参数的数量没有限制 AFAIK。为了满足您对 xpath 的好奇心,我建议您使用 xpath 工具(这是one of them,或者谷歌找到很多替代品并选择您喜欢的任何人)。将您的 XML 粘贴到那里并尝试任何您可以轻松想到的 xpath 查询,然后在您的 VBA 代码中实际使用它
    • 这是一个很棒的资源,谢谢!如果你不介意,请看看这个并给我你的意见stackoverflow.com/questions/29722275/…
    猜你喜欢
    • 1970-01-01
    • 2023-03-29
    • 1970-01-01
    • 2015-05-18
    • 1970-01-01
    • 2011-07-14
    • 2015-06-20
    • 2020-12-16
    相关资源
    最近更新 更多