2015-04-17 53 views
0

我的程序掃描名爲「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

關於問題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" 
..... 
+0

感謝您的答覆。對於問題1,如果StoreLocation節點不存在並且版本節點會怎麼辦? – NRH

+0

如果我們想在包含一個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

+1

@NRH都是有效的,應該工作(如果我理解你正確),並沒有限制xpath參數AFAIK的數量。爲了滿足你即將到來的關於xpath的好奇心,我建議在xpath工具(這是[其中之一](http://www.freeformatter.com/xpath-tester.html)或谷歌找到很多選擇和挑選你喜歡的人)。粘貼你的XML,然後嘗試任何你可以想到的xpath查詢,而不用麻煩,然後在VBA代碼中實際使用它。 – har07