问题描述
我需要帮助更新 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