Excel VBA:如何删除/注入特定XPath下的所有节点?

时间:2013-10-22 08:41:04

标签: xml parsing vba excel-vba xpath

我无法实现一个循环,它应该删除XPath下的所有节点。 删除这些节点后,另一个循环应该从第二个文档中注入节点。所以基本上我想用新数据替换现有文件中的旧数据。

我认为我已经涵盖了基本框架,但是,我猜测XPath本身仍然存在一些问题。此外,我无法获得任何方法来删除工作的孩子:(

如果有人能够把我推向正确的方向,我将非常感激,因为我基本上没有关于使用VBA进行XML解析的先验知识。

最好的问候, daZza

到目前为止,这是我的代码:

VBA:

Sub injectXML()

Dim sourceXML As DOMDocument60
Dim targetXML As DOMDocument60
Dim sourceNList As IXMLDOMNodeList 
Dim sourceNode As IXMLDOMNode
Dim targetNList As IXMLDOMNodeList
Dim targetNode As IXMLDOMNode
Dim sourceAttributes As IXMLDOMNamedNodeMap
Dim targetAttributes As IXMLDOMNamedNodeMap

Set sourceXML = New DOMDocument60
sourceXML.Load ("C:\...\source.xml")

Set targetXML = New DOMDocument60
targetXML.Load ("C:\...\target.xml")

sourceXML.async = False
sourceXML.validateOnParse = False
targetXML.async = False
targetXML.validateOnParse = False

Set sourceNList = sourceXML.SelectNodes("//test/TLRule")
Set targetNList = targetXML.SelectNodes("//RuleCollection/TLRule/TLRule")


For Each targetNode In targetNList

    [remove the node]   

Next targetNode


For Each sourceNode In sourceNList

    [append all Data from source.xml to target.xml]  

Next sourceNode


sourceXML.Save ("C:\...\target.XML")

End Sub

源XML结构:

<test>
    <TLRule>
        <RuleCommand>
            <RuleID Value="0004" />
        </RuleCommand>
    </TLRule>
    <TLRule>
        <RuleCommand>
            <RuleID Value="0005" />
        </RuleCommand>
    </TLRule>
</test>

目标XML结构:

<RuleCollection>
     <TLRule>

        [lots of other data in <TLRule> + child tags]

        <TLRule>
            <RuleCommand>
                <RuleID Value="0004" />
        <TLRule>
    <TLRule>
<RuleCollection>

修改

感谢Martin,我能够完成宏的第一部分(删除所有旧数据)。

Set targetNList = targetXML.SelectNodes("//RuleCollection/TLRule/TLRule/RuleCommand")
Set targetNListSubstitution =    targetXML.SelectNodes("//RuleCollection/TLRule/TLRule/RuleSubstitution")
Set targetNListCleanUp = targetXML.SelectNodes("//RuleCollection/TLRule/TLRule")


For Each Item In targetNList
    Item.ParentNode.RemoveChild (Item)
Next


For Each Item In targetNListSubstitution
    Item.ParentNode.RemoveChild (Item)
Next


For Each Item In targetNListCleanUp
    If Item.HasChildNodes = False Then Item.ParentNode.RemoveChild (Item)
Next

现在我只需要从sourceXML / sourceNList中注入所有数据。 这似乎是任务中最难的部分,因为它需要在我使用上述方法删除旧数据的地方注入。

从我的角度来看,我需要一些锚点/指针,但我只是看不出我会怎样在那里。

也许有些人可以提供帮助?非常感谢。

最好的问候, daZza

1 个答案:

答案 0 :(得分:1)

我认为

Set targetNList = targetXML.SelectNodes("//RuleCollection/TLRule/TLRule")


For Each targetNode In targetNList

    [remove the node]   

Next targetNode

可以实现为

Set targetNList = targetXML.SelectNodes("//RuleCollection/TLRule/TLRule")

For Each item In targetNList
  item.parentNode.removeChild item
Next

当您的路径/RuleCollection/TLRule/TLRule/RuleCommand//RuleCollection/TLRule/TLRule/RuleSubstitution选择//RuleCollection/TLRule/TLRule的子节点时,在For Each上运行targetXML.SelectNodes("//RuleCollection/TLRule/TLRule")循环就足够了。

至于从其他文档中插入节点,我认为你可以使用例如。

Set target = targetXML.selectSingleNode("//RuleCollection/TLRule")
For Each sourceNode In sourceNList
  target.appendChild sourceNode
Next