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