【问题标题】:Could not select elements nodes but can select attributes only .VBA -XML无法选择元素节点,但只能选择属性 .VBA -XML
【发布时间】:2018-05-10 23:15:03
【问题描述】:

我有来自 IPC1752 架构的 XML,我必须根据我的 excel 数据表填写值。所以我必须做这些事情

1.将 XML 加载到我的 VBA 中 2.用我存储在excel单元格中的值更改XML中的所需值 3.将修改后的XML保存到文件夹

'子UpdateXML() 调用 fnUpdateXMLByTags 结束子

函数 fnUpdateXMLByTags() 将 mainWorkBook 调暗为工作簿 将 wrsht 调暗为工作表

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(attributes) 时,它的工作 [example:oXMLFile.SelectNodes("//@itemName")]

但在我使用 selectnodes(elements) 时不起作用 [example:oXMLFile.SelectNodes("//Substance")]

请帮忙。

这里是 XML https://www.jiocloud.com/s/?t=SzqFJhEABfsTQfZW&s=a2

【问题讨论】:

  • 想要的结果是什么?您到底想从需要帮助的 xml 中提取什么?您要选择所有元素吗?
  • 我很抱歉,因为我在问题陈述中没有很好地解释。假设我必须在父节点下添加一个节点我必须首先选择一个父节点并附加一个子节点对吗?我无法选择所需的元素。但我可以用所需的值更改属性值。那么在选择元素时我错在哪里?我现在清楚了吗兄弟?
  • 这里是我要填写XML的excel数据jiocloud.com/s/?t=cpVDieMyifUMVEXJ&s=a2
  • 我回答了你原来的问题。这是一个新问题,应该这样发布,然后我会很乐意回答。如果您愿意,可以将此问题回滚到之前的问题。
  • 另外,根据命名空间建议找到自己的解决方案做得很好。请记住发布作为答案,以便其他人可以从中学习。另外,如果它被赞成,你会得到代表点。可能值得添加一条说明,说明您选择该特定名称空间的原因以及添加它的价值,而不是简单地排除我提到的名称空间。

标签: xml vba excel selectnodes


【解决方案1】:

这让我如厕了一段时间,直到我意识到它与命名空间有关。您需要删除:

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

来自 xml。

然后您可以使用 Xpath 进行导航,例如:

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 does not work for selecting in XML

【讨论】:

  • 非常感谢。它在删除 xmlns 后工作。但实际上,我不知道该行对 XML 文件有多重要,假设我想保留它,即选择节点而不删除 xmlns 。有什么办法吗?
  • 您不能再使用 XPath。请参阅我关于如何循环和选择元素节点的答案的第二部分。
  • 我提供了更多信息作为指导。请让我知道这还缺少什么。
  • 谢谢,@Qharr。同时,我找到了另一种方法 "XmlNamespaces = "xmlns:d='webstds.ipc.org/175x/2.0'" oXMLFile.SetProperty "SelectionNamespaces", XmlNamespaces" 然后 Set SubstanceCategoryNode = oXMLFile.SelectNodes("//d:SubstanceCategory") 这也有效。
【解决方案2】:

我通过使用命名空间管理器解决了这个问题。感谢@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")

【讨论】:

  • 干得好。 +1。为什么选择这个特定的命名空间?
猜你喜欢
  • 2023-04-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多