Не удалось выбрать узлы элементов, но можно выбрать только атрибуты .VBA -XML - PullRequest
0 голосов
/ 08 мая 2018

У меня есть XML из схемы IPC1752, где я должен заполнить значения в соответствии с моим паспортом Excel. поэтому я должен сделать эти вещи

1. загрузить XML в мой VBA 2. измените желаемое значение в XML на значения, которые я храню в ячейке Excel 3. сохранить измененный XML в папку

'Sub UpdateXML () Вызовите fnUpdateXMLByTags End Sub

Функция fnUpdateXMLByTags () Dim mainWorkBook As Workbook Dim wrsht As Worksheet

Set mainWorkBook = ActiveWorkbook
Set wrsht = mainWorkBook.Sheets("Sheet1")
wrsht.Activate

Dim oXMLFile As MSXML2.DOMDocument60
Set oXMLFile = New MSXML2.DOMDocument60
oXMLFile.async = False
oXMLFile.validateOnParse = False
XMLFileName = "Z:\IPC\IPC1752A_WK-200264-000 - Copy.xml"


For i = 3 To 5
  If Not IsEmpty(mainWorkBook.Sheets("Sheet1").Range("A" & i)) Then

        PartID = mainWorkBook.Sheets("Sheet1").Range("A" & i).Value
        PartName = mainWorkBook.Sheets("Sheet1").Range("B" & i).Value
        MaterialName = mainWorkBook.Sheets("Sheet1").Range("D" & i).Value
        MassAmount = mainWorkBook.Sheets("Sheet1").Range("F" & i).Value
        MassUnit = mainWorkBook.Sheets("Sheet1").Range("G" & i).Value
        Path = "D:\New folder\" & PartID & ".xml"

        If oXMLFile.Load(XMLFileName) Then
            Set PartIDNodes = oXMLFile.SelectNodes("//@itemNumber")
            Set PartNameNodes = oXMLFile.SelectNodes("//@itemName")
            Set MaterialNameNodes = oXMLFile.SelectNodes("//@name")
            Set MassAmountNodes = oXMLFile.SelectNodes("//@value")
            Set MassUnitNodes = oXMLFile.SelectNodes("//@UOM")
            PartIDNodes(0).NodeValue = Part_ID
            PartNameNodes(0).NodeValue = PartName
            MaterialNameNodes(5).NodeValue = MaterialName
            MassAmountNodes(1).NodeValue = MassAmount
            MassUnitNodes(1).NodeValue = MassUnit
            Set ParentNodes = oXMLFile.SelectNodes("//Substance")
           MsgBox ParentNodes.Length '->is showing zero
        End If


End If
Next i
End Function

здесь, когда я использую selectnodes (атрибуты), он работает [пример: oXMLFile.SelectNodes ("// @ itemName")]

но не работает, когда я использую selectnodes (elements) [пример: oXMLFile.SelectNodes ("// Substance")]]

пожалуйста, помогите.

Вот XML https://www.jiocloud.com/s/?t=SzqFJhEABfsTQfZW&s=a2

Ответы [ 2 ]

0 голосов
/ 10 мая 2018

Я решил это с помощью менеджера пространства имен. благодаря @Qharr вот оно

... часть кода ...

XmlNamespaces = "xmlns:d='http://webstds.ipc.org/175x/2.0'"
oXMLFile.SetProperty "SelectionNamespaces", XmlNamespaces


If IsEmpty(mainWorkBook.Sheets("Sheet1").Range("D" & i)) Then
Substancename = mainWorkBook.Sheets("Sheet1").Range("H" & i).Value
CASNumber = mainWorkBook.Sheets("Sheet1").Range("I" & i).Value
SubAmount = mainWorkBook.Sheets("Sheet1").Range("J" & i).Value
Set SubstanceCategoryNode = oXMLFile.SelectNodes("//d:SubstanceCategory")

Установить Substancenode = oXMLFile.createElement ("d: Substance")

0 голосов
/ 08 мая 2018

Это вело мой горшок некоторое время, пока я не понял, что это связано с пространством имен. Вам необходимо удалить:

 xmlns="http://webstds.ipc.org/175x/2.0" 

из XML.

Затем вы можете перемещаться по Xpath, например ::1006*.

Public Sub test()
'Remove namespace info: ===>   xmlns="http://webstds.ipc.org/175x/2.0" 

    Dim xml As String, doc As MSXML2.DOMDocument60

    xml = [A1].Text

    Set doc = New MSXML2.DOMDocument60

    If Not doc.LoadXML(xml) Then
        Err.Raise doc.parseError.ErrorCode, , doc.parseError.reason
        Exit Sub
    End If

    Dim nodeList As Object

    Set nodeList = doc.SelectNodes("//Substance")
    Debug.Print nodeList.Length
End Sub

Другой метод:

Это выбирает узлы элементов на основе NodeType. Я положил ваш xml в ячейку A1.

Option Explicit

Public Sub test()
    Dim xml As String, doc As MSXML2.DOMDocument60

    xml = [A1].Text
    Set doc = New MSXML2.DOMDocument60

    If Not doc.LoadXML(xml) Then
        Err.Raise doc.parseError.ErrorCode, , doc.parseError.reason
        Exit Sub
    End If

    ''Use the nodeType property to only process element nodes
    Dim node As IXMLDOMElement
    For Each node In doc.DocumentElement.ChildNodes
        If node.NodeType = 1 Then
            Debug.Print node.nodeName
        End If
    Next node

End Sub

Более хрупкий, но спускающийся по дереву, используя XPath:

/MainDeclaration[@xmlns="http://webstds.ipc.org/175x/2.0"]/Product[@unitType="Each"]/MaterialInfo/HomogeneousMaterialList/HomogeneousMaterial[@name="UNS C36000"]/SubstanceCategoryList

в качестве руководства:

Dim node As IXMLDOMElement
Set node = doc.DocumentElement.LastChild.ChildNodes(1).FirstChild.FirstChild.ChildNodes(1).ChildNodes(1) 

'^^ Above is: MainDeclaration> Product > MaterialInfo > HomogeneousMaterialList> HomogeneousMaterial > SubstanceCategoryList > SubstanceCategory

Dim i As Long
For i = 0 To node.ChildNodes.Length - 1
    Debug.Print node.ChildNodes(i).BaseName  '<== Substance
Next i

Справка:

  1. https://www.w3schools.com/xml/dom_nodes_access.asp
  2. https://www.w3schools.com/jsref/prop_node_nodetype.asp
  3. XPath не работает для выбора в XML
...