我想在一个xml文档中将第四个“模型”节点(具有“有限公司”的节点)作为客户,并将其(完整地)移动到新的空xml文档。我已经看到了一些关于在VB和Java中做这种事情的线程,但它们对我想要做的事情并没有太大的帮助(并且它们都没有使用VBA)。然而,他们确实做了类似我最后两行代码的事情,但我不能在最后一行中遇到错误。如何将此节点附加到新文档?我敢肯定我可能会遗漏一些非常愚蠢的东西。它是什么?我使用importNode错了吗?
我的xmls。 FILENAME1:
<?xml version="1.0" encoding="utf-8"?>
<MyFile xmlns="urn:MyFile-schema">
<Files>New</Files>
<Source>Imported</Source>
<Destination>Kia</Destination>
<Auto>Sofia </Auto>
<User>MMOUSE</User>
<TimeStamp>2017-11-13T10:00:00</TimeStamp>
<Model Source="Yes">
<Customer>Jeff Mills</Customer>
<CustomerCategory>Individual</CustomerCategory>
<Vehicle>
<VehicleName>Liona</VehicleName>
<Door>
<DoorColor>Brown</DoorColor>
</Door>
<Door>
<DoorColor>Black</DoorColor>
</Door>
</Vehicle>
</Model>
<Model Source="Yes">
<Customer>Jen Mills</Customer>
<CustomerCategory>Individual</CustomerCategory>
<Vehicle>
<VehicleName>Cleo</VehicleName>
<Door>
<DoorColor>Brown</DoorColor>
</Door>
<Door>
<DoorColor>Black</DoorColor>
</Door>
</Vehicle>
</Model>
<Model Source="Yes">
<Customer>Dan Blackburn</Customer>
<CustomerCategory>Individual</CustomerCategory>
<Vehicle>
<VehicleName>Christina</VehicleName>
<Door>
<DoorColor>Brown</DoorColor>
</Door>
<Door>
<DoorColor>Black</DoorColor>
</Door>
</Vehicle>
</Model>
<Model Source="Yes">
<Customer>Limited Company</Customer>
<CustomerCategory>Corp</CustomerCategory>
<Vehicle>
<VehicleName>Jasmine</VehicleName>
<Door>
<DoorColor>red</DoorColor>
</Door>
<Door>
<DoorColor>red</DoorColor>
</Door>
</Vehicle>
</Model>
</MyFile>
文件名2:
<?xml version="1.0" encoding="utf-8"?>
<MyFile xmlns="urn:MyFile-schema">
<Files>New</Files>
<Source>Imported</Source>
<Destination>Kia</Destination>
<Auto>Sofia </Auto>
<User>MMOUSE</User>
<TimeStamp>2017-11-13T10:00:00</TimeStamp>
</MyFile>
我希望fileName2在添加后看起来像这样:
<?xml version="1.0" encoding="utf-8"?>
<MyFile xmlns="urn:MyFile-schema">
<Files>New</Files>
<Source>Imported</Source>
<Destination>Kia</Destination>
<Auto>Sofia </Auto>
<User>MMOUSE</User>
<TimeStamp>2017-11-13T10:00:00</TimeStamp>
<Model Source="Yes">
<Customer>Limited Company</Customer>
<CustomerCategory>Corp</CustomerCategory>
<Vehicle>
<VehicleName>Jasmine</VehicleName>
<Door>
<DoorColor>red</DoorColor>
</Door>
<Door>
<DoorColor>red</DoorColor>
</Door>
</Vehicle>
</Model>
</MyFile>
我的代码一直在最后一行抛出错误
“运行时错误'438':对象不支持此属性或方法”
这就是我所拥有的:
Option Explicit
Sub MoveNode()
'Declare Objects
Dim oldDoc As MSXML2.DOMDocument60 'Object for the oldDoc
Dim newDoc As MSXML2.DOMDocument60 'Object for the newDoc
Dim newNode As IXMLDOMNode 'for the new node
'Initialize objects and Variables
Set oldDoc = New MSXML2.DOMDocument60
Set newDoc = New MSXML2.DOMDocument60
oldDoc.validateOnParse = False
newDoc.validateOnParse = False
‘some code to get filename and path from user and store as fileName1 and fileName2
'Load the docs
oldDoc.Load fileName1
oldDoc.setProperty "SelectionNamespaces", "xmlns:prefix='urn:MyFile-schema'"
newDoc.Load fileName2
newDoc.setProperty "SelectionNamespaces", "xmlns:prefix='urn:MyFile-schema'"
Set newNode = newDoc.importNode(oldDoc.SelectSingleNode("//prefix:Model[4]"), True)
newDoc.SelectSingleNode("//prefix:MyFile").appendChild (newNode)
End Sub
答案 0 :(得分:1)
由于@MathieuGuindon在括号中确定了包装参数的主要问题,您可以简单地删除或分配给另一个对象:
newDoc.SelectSingleNode("//prefix:MyFile").appendChild xNode
或者,将其指定为函数
Dim var As Variant
Set var = newDoc.SelectSingleNode("//prefix:MyFile").appendChild(xNode)
考虑以下最佳做法调整:
parseError
。[4]
,以防第一个XML可以更改排序。< / LI>
.Save
以将修改后的 newDoc 输出到文件。set
个对象,并可能为用户提供成功消息。<强> VBA 强>
Sub MoveNode()
On Error GoTo ErrHandle
'Declare Objects
Dim srcfilename As String, addfilename As String, outputfilename As String
Dim srcDoc As MSXML2.DOMDocument60, addDoc As MSXML2.DOMDocument60
Dim xNode As IXMLDOMNode, newNode As IXMLDOMNode
'Initialize objects and Variables
Set srcDoc = New MSXML2.DOMDocument60
Set addDoc = New MSXML2.DOMDocument60
srcDoc.validateOnParse = False
addDoc.validateOnParse = False
'some code to get filenames from user
srcfilename = "C:\Path\To\Source.xml"
addfilename = "C:\Path\To\Add_Info.xml"
outputfilename = "C:\Path\To\Output.xml"
'Load the docs
srcDoc.Load srcfilename
srcDoc.setProperty "SelectionNamespaces", "xmlns:prefix='urn:MyFile-schema'"
addDoc.Load addfilename
addDoc.setProperty "SelectionNamespaces", "xmlns:prefix='urn:MyFile-schema'"
'Parse docs
Set xNode = srcDoc.importNode(addDoc.SelectSingleNode("//prefix:Model[prefix:Customer='Limited Company']"), True)
srcDoc.SelectSingleNode("//prefix:MyFile").appendChild xNode
srcDoc.Save outpfilename
MsgBox "Successfully added node to original XML!", vbInformation
GoTo ExitHandle
ExitHandle:
Set srcDoc = Nothing: Set addDoc = Nothing: Set xNode = Nothing: Set newNode = Nothing
Exit Sub
ErrHandle:
MsgBox Err.Number & " - " & Err.Description, vbCritical
Err.Raise srcDoc.parseError.ErrorCode, , srcDoc.parseError.reason
Resume ExitHandle
End Sub
答案 1 :(得分:1)
因为我会放弃这个机会,所以还要考虑XSLT,这是一种用于操作XML文件的转换语言。 MSXML库可以运行XSLT 1.0脚本,XSLT维护document()
函数,因此可以解析XML文件。务必将源和添加信息文档放在同一文件夹中。
XSLT (另存为.xsl文件,一个特殊的.xml文件)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:doc="urn:MyFile-schema" >
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="doc:MyFile">
<xsl:copy>
<xsl:apply-templates />
<xsl:copy-of select="document('Add_Info.xml')/doc:MyFile
/doc:Model[doc:Customer='Limited Company']" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
<强> VBA 强>
Sub XSLTransform()
On Error GoTo ErrHandle
Dim xmldoc As New MSXML2.DOMDocument, xslDoc As New MSXML2.DOMDocument, newDoc As New MSXML2.DOMDocument
' LOAD XML AND XSL FILES
xmlDoc.async = False
xmldoc.Load "C:\Path\To\Source.xml"
xslDoc.async = False
xslDoc.Load "C:\Path\To\XSLT_Script.xsl"
' TRANSFORM XML
xmldoc.transformNodeToObject xslDoc, newDoc
newDoc.Save "C:\Path\To\Output.xml"
MsgBox "Successfully transformed XML!", vbInformation
GoTo ExitHandle
ExitHandle:
Set xmldoc = Nothing: Set xslDoc = Nothing: Set newDoc = Nothing
Exit Sub
ErrHandle:
MsgBox Err.Number & " - " & Err.Description, vbCritical
Err.Raise xslDoc.parseError.ErrorCode, , xslDoc.parseError.reason
Resume ExitHandle
End Sub
XSLT的美妙之处在于它是可移植的,不需要MSXML来运行它。因此,即使是Java或Python或PHP也可以运行它来呈现相同的输出!您还可以在同一个脚本中运行其他操作,例如添加其他节点,更改节点名称,文本值等。