2015-09-22 50 views
0

我想寫一個Excel VBA腳本來選擇性地從xml文件中獲取信息並用該信息製作一個表格。VBA XML讀取節點,如果屬性= 1,則讀取該節點中的其他屬性。對所有節點都這樣做

有數千個節點全名缺陷,每個缺陷都有屬性。 我想在每個缺陷中使用一個屬性來過濾一些不需要的缺陷,並且希望的缺陷列出名爲defect的所有其他屬性。

請參閱下面的更多信息。 nextSibling不能使用。

XML結構:

<!-- language: xml --> 
<?xml version="1.0" encoding="WINDOWS-1252"?> 
<CDXML> 
<DATA><FaceInformation><Defects> 
<Defect> 
    <Black Type="Integer" Value="1"/> 
    <Dots Type="Integer" Value="21"/> 
    <Height Type="Integer" Value="1"/> 
</Defect> 
<Defect> 
    <Black Type="Integer" Value="0"/> 
    <Dots Type="Integer" Value="22"/> 
    <Height Type="Integer" Value="2"/> 
</Defect> 
<Defect> 
    <Black Type="Integer" Value="1"/> 
    <Dots Type="Integer" Value="23"/> 
    <Height Type="Integer" Value="3"/> 
</Defect> 
</Defects></FaceInformation></DATA> 

所需的輸出:

<!-- language: lang-none --> 
Black Dots  Height 
1  21  1 
1  22  3 

VBA:

<!-- language: lang-vb --> 
Dim xmlDoc As DOMDocument30 
Set xmlDoc = New DOMDocument30 
xmlDoc.async = False 
Dim n, m As IXMLDOMNode 
Dim j As Integer 

XMLFileName = C:\1.xml 
xmlDoc.Load (XMLFileName) 

'This goes through all the attributes with the name Black, 
'this is okay since Black only appear once in each node called defect. 
For Each n In xmlDoc.SelectNodes("//Defects/Defect/Black") 
    'Read value of the Black attribute 
    Black = n.Attributes.getNamedItem("Value").Text 
    If Black <> "0" Then 'Print if 1 
     Cells(j + 3, 2) = Black 
     'I can not use nextSibling because the order of defects is not always the same 
     For Each m In n.SelectNodes("DefectClass") 
      Dots = m.Attributes.getNamedItem("Value").Text 
      'I have no idea what to do from this point 
      Cells(i + 3, 3) = Dots 
     Next 
     j = j + 1 
    End If 
Next 
+0

對我來說顯得有些錯字的錯誤,如'XMLFileName = C:\ 1.XML '應該是引號內的'「XMLFileName = C: \ 1.xml 「'。進一步'Dim xmlDoc As DOMDocument30'給我的excel 2007系統編譯器錯誤。如果我使它成爲'DOMDocument60',這是可以接受的。我看着堆棧溢出舊帖子,並發現一個由@David Zemens相關和有趣。從他的計劃中獲取線索,我希望你能夠繼續下去。 – skkakkar

回答

0

我想你可以使用的XMLDOM功能的完整程度上實現你的任務。我不確定你正在使用哪個庫,但我已經使用了Microsoft XML, v6.0

  1. 確保您的XML是正確的。我認爲它可能會丟失</CDXML>結束標記。
  2. 確保您的文件名是使用xmlDoc.Load(filename)時的字符串。
  3. 我不知道你的措辭是否會引起你的困惑。 <Defect>元素沒有屬性。它有三個子元素,它們本身具有屬性 - 正是這些屬性是你所追求的。
  4. SelectNodes()函數傳遞一個包含屬性過濾器的查詢字符串,如下所示:"//Black[@Value!=""0""]"。您可以使用此功能獲取您的目標元素。
  5. 如果你不願循環通過兄弟姐妹,那麼你可以派生父節點,然後按名稱選擇你的目標子節點。謝天謝地,XMLDOM模型將返回Nothing而不是錯誤,如果沒有找到節點,顯然,它不擔心節點的順序,他們只需要是父節點的子節點。所以你可以簡單地檢查你的所有屬性都不是Nothing,然後把這些值寫入你的excel表格。

所以,你的代碼可能是這個樣子:

Dim xmlFileName As String 
Dim xmlDoc As DOMDocument 
Dim nodeList As IXMLDOMNodeList 
Dim node As IXMLDOMNode 
Dim query As String 
Dim black As IXMLDOMAttribute 
Dim dots As IXMLDOMAttribute 
Dim height As IXMLDOMAttribute 
Dim rng As Range 

Set xmlDoc = New DOMDocument30 
xmlDoc.async = False 

xmlFileName = "C:\1.xml" 
query = "//Black[@Value!=""0""]" 

xmlDoc.Load (xmlFileName) 
Set nodeList = xmlDoc.SelectNodes(query) 

If Not nodeList Is Nothing Then 
    Set rng = ThisWorkbook.Worksheets("Sheet1").Range("A1").Resize(, 3) 
    rng.Value = Array("Black", "Dots", "Height") 
    Set rng = rng.Offset(1) 

    For Each node In nodeList 
     Set black = node.Attributes.getNamedItem("Value") 
     Set dots = node.ParentNode.SelectSingleNode("Dots").Attributes.getNamedItem("Value") 
     Set height = node.ParentNode.SelectSingleNode("Height").Attributes.getNamedItem("Value") 

     If Not black Is Nothing And Not dots Is Nothing And Not height Is Nothing Then 
      rng.Value = Array(black.Text, dots.Text, height.Text) 
      Set rng = rng.Offset(1) 
     End If 
    Next 
Else 
    MsgBox "No elements found using the query: " & query 
End If 
+0

謝謝你的患者,我給出的信息有很多錯誤。 我從這裏學到了很多東西。 –