微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

MSXML2:如何使用 XPATH

如何解决MSXML2:如何使用 XPATH

我需要帮助更新 XML 文件的特定节点。我使用 MSXML2.DOMDocument60。这段代码演示了这个想法:

Option Explicit

Sub UpdateXML()
    'Load the XML file into odoc
    Dim odoc As MSXML2.DOMDocument60
    Set odoc = New MSXML2.DOMDocument60
    If Not odoc.Load("C:\1\test.xml") Then
        Debug.Print odoc.parseError
        Exit Sub
    End If
    
    Dim xPath As String
    'Lets say I want to update this node:
    xPath = "/root/devices/device[@name='DB']/package[@name='DIL8']/technologies"
    
    Dim sNode As IXMLDOMNode
    'I kNow how to select it
    Set sNode = odoc.selectSingleNode(xPath)
    
    If Not sNode Is nothing Then
        Debug.Print sNode.XML
        
        'This function returns the node with new data (function follows)
        Debug.Print getTechnologies.XML
        
        'Here I need to insert the data returned by getTechnologies()
        'into the correct place of the odoc (specified by xPath)
        
        'this does not work
        odoc.selectSingleNode(xPath) = getTechnologies
        '??? odoc.replaceChild ??? I'm lost here
         
        'It would be great to see the example how to insert and delete
        'the node <technologies> of the odoc using xPath... if it is possible of course.
        
    End If
    
    'Save modified data into new file
    odoc.Save "C:\1\final.xml"
    
    'Final file should Now contain "newValue" within the
    '/root/devices/device[@name='DB']/package[@name='DIL8']/technologies
End Sub

Function getTechnologies() As IXMLDOMNode
    'This is just a simplified example to demonstrate the function
    'that returns the IXMLDOMNode object
    'In real,this function pulls data from a database
    
    Dim oNode As MSXML2.DOMDocument60
    Set oNode = New MSXML2.DOMDocument60
    Dim sXml As String
    sXml = "<technologies>" & vbCrLf & _
           "    <property name='prop1' value='newValue'/>" & vbCrLf & _
           "    <property name='prop2' value='newValue'/>" & vbCrLf & _
           "    <property name='prop3' value='newValue'/>" & vbCrLf & _
           "    <property name='prop4' value='newValue'/>" & vbCrLf & _
           "</technologies>"
    If Not oNode.loadXML(sXml) Then
        Debug.Print oNode.parseError
    Else
        Set getTechnologies = oNode.selectSingleNode("/technologies")
    End If
End Function

这是我在示例中使用的文件 test.xml。它是真实文件的简化版本:

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <library>
        <items>
            <item name="foo"/>
            <item name="bar"/>
            <item name="foo2"/>
            <item name="bar2"/>
        </items>
    </library>
    <devices>
        <device name="DB">
            <package name="DIL4">
                <something>Another tree Could be here</something>
                <technologies>
                    <property name="prop1" value="oldValue"/>
                    <property name="prop2" value="oldValue"/>
                    <property name="prop3" value="oldValue"/>
                    <property name="prop4" value="oldValue"/>
                </technologies>
            </package>
            <package name="DIL8">
                <technologies>
                    <property name="prop1" value="oldValue"/>
                    <property name="prop2" value="oldValue"/>
                    <property name="prop3" value="oldValue"/>
                    <property name="prop4" value="oldValue"/>
                </technologies>
                <something>The order is not guaranteed</something>
            </package>
            <package name="DIL16">
                <technologies>
                    <property name="prop1" value="oldValue"/>
                    <property name="prop2" value="oldValue"/>
                    <property name="prop3" value="oldValue"/>
                    <property name="prop4" value="oldValue"/>
                </technologies>
            </package>
        </device>
        <device name="NPN">
            <package name="SOT23">
                <technologies>
                    <property name="prop1" value="oldValue"/>
                    <property name="prop2" value="oldValue"/>
                    <property name="prop3" value="oldValue"/>
                    <property name="prop4" value="oldValue"/>
                </technologies>
            </package>
        </device>
    </devices>
</root>

编辑:下面是 this answer代码,但我不明白修改 xmlRoot 如何影响 xmlDoc - 是 byRef 吗? (见代码中的注释)

Sub XMLtest()
Dim myVar As String,pathToXML As String
Dim xmlDoc As Object,xmlRoot As Object
    Set xmlDoc = CreateObject("MSXML2.DOMDocument")
    pathToXML = "N:\example.xml" '<--- change the path
    Call xmlDoc.Load(pathToXML)
    Set xmlRoot = xmlDoc.getElementsByTagName("RefTest").Item(0)
    myVar = "foobar" '<--- your value

    'Here the xmlRoot object is updated
    xmlRoot.selectSingleNode("iRef5").Text = myVar
    
    'Here the xmlDoc is saved
    Call xmlDoc.Save(pathToXML)
End Sub

感觉答案就在眼前,却看不到

解决方法

简单的xml文件:

<?xml version="1.0"?>
<!-- This file represents a fragment of a bookstore inventory database -->
<bookstore specialty="novel">
  <book>
    <Title>Beginning XML</Title>
    <Publisher>Wrox</Publisher>
  </book>
  <book>
    <Title>Professional XML</Title>
    <Publisher>Wrox</Publisher>
  </book>
  <book>
    <Title>Programming ADO</Title>
    <author>
      <first-name>Mary</first-name>
      <last-name>Jones</last-name>      
    </author>
    <datePublished>1/1/2000</datePublished>
    <Publisher>Microsoft Press</Publisher>
  </book>
</bookstore>

以下对我来说可以编辑单个节点。

Dim oDoc As MSXML2.DOMDocument60,sNode As MSXML2.IXMLDOMNode
Set oDoc = New MSXML2.DOMDocument60
oDoc.Load "path\filename"
Set sNode = oDoc.SelectSingleNode("//book[3]/Title") 'selection criteria using XPath syntax
sNode.Text = "something"
oDoc.Save("path\filename") 'If same path\filename is used,it will overwrite.
,

整个问题是我认为 <input type="hidden" name="token" id="token">oDoc 对象是相互独立的。我没有意识到 sNode 是对 sNode 节点的主动引用。感谢 June7 的回答,我明白了它是如何工作的,然后只花了一点时间就找到了我最初想到的所有 3 个问题的答案:

oDoc

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。