XML文件输出仅显示字节顺序标记
我有一个试图解析的XML文件,其内容与下面的XML完全相同:XML文件输出仅显示字节顺序标记,xml,vba,dom,byte-order-mark,Xml,Vba,Dom,Byte Order Mark,我有一个试图解析的XML文件,其内容与下面的XML完全相同: <Results xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <Reference>{REFERENCE-HERE}</Reference> <FillerTags>Filler</FillerTags> &l
<Results xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Reference>{REFERENCE-HERE}</Reference>
<FillerTags>Filler</FillerTags>
<entity>
<entityName>ABC</entityName>
<entityId>012345</entityId>
</entity>
<Items>
<Item>
<FillerTagsAgain>Filler2</FillerTagsAgain>
<FillerTagsAgain>Filler2</FillerTagsAgain>
<FillerTagsAgain>Filler2</FillerTagsAgain>
</Item>
<AnotherItem>
<FillerTagsAgain>Filler2</FillerTagsAgain>
<FillerTagsAgain>Filler2</FillerTagsAgain>
<FillerTagsAgain>Filler2</FillerTagsAgain>
</AnotherItem>
</Items>
</Results>
可以肯定的是,代码不会产生错误——它创建了一个新文件,但它创建的文件不正确。正确的输出应该是(对于尝试过此代码的其他人来说也是如此):
更新3:现在一切都很完美。唯一的问题是上述准则所执行的实际程序。由于存在多个实体,并且每组项都属于一个实体,因此代码需要找到一个entityId,并将该entityId应用于entityId标记另一次出现之前的所有项。在这一点之后,一切都会重复。我把这个作为一个答案放在这里,这样我可以清楚地显示我的代码。如果此操作也失败,则将删除。尝试此语法以使用另一种写入文件的方法。Notepadd++告诉我这是ANSII:
'## Create an FSO to write the new file'
Set fso = CreateObject("Scripting.FileSystemObject")
Dim FF As Integer
FF = FreeFile
'## Attempt to write the new/modified XML to file'
fso.CreateTextFile newFilePath
Open newFilePath For Output As FF
Print #FF, dom.XML
Close #FF
或者
(同样,仅覆盖基础,并将根据需要进行更新或删除)
尝试:
差异是CreateTextFile
方法中的第三个参数,它指定是将文件创建为Unicode(True
)还是ASCII(False
)
Notepad++确认此方法是ANSII,而如果我创建Unicode文件时使用True
,则会得到一个UCS-2 Little-Endian文件
我个人没有注意到Ascii/Unicode之间的区别——我可以在记事本或记事本++中打开它们,并且它们在我看来是一样的,但因为这似乎可能是一个字符编码问题,所以值得一试。我建议它只是作为第一个(也是最简单的)实现选项(如果需要,还有更多的选项需要探索)
更新#3
要解决文件的嵌套性质。。。基本上,您有XML元素同级(“实体”和“项”),并且需要修改“项”(及其子节点)以包含“entityId”(是“实体”的子节点)。我正在解释这种关系,希望这种修改是有意义的
'##### NO LONGER USED:'
'# Get the entityID node'
'Set Customer = DOM.DocumentElement.getElementsByTagName("CustomerId")(0)'
Dim itm As IXMLDOMNode
'# Instead of getting the first item like we did before, we can iterate the collection'
' of nodes with the entityID tag like so:'
For Each Customer In DOM.DocumentElement.getElementsByTagName("entityId")
'Since Item is Entity nextSibling, and Entity is parent of entityId,'
' we can iterate the collection if its childNodes like this:'
For Each itm In Customer.ParentNode.NextSibling.ChildNodes
If itm.HasChildNodes Then
'# Insert this node before the first child node of Item'
itm.InsertBefore Customer.CloneNode(True), itm.FirstChild
Else
'# Append this node to the Item'
itm.appendChild Customer.CloneNode(True)
End If
Next
Next
'##### This function call is no longer needed
'AppendCustomer DOM, "Transaction", Customer'
这将生成类似以下内容的XML:
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Results>
<Reference>{REFERENCE-HERE}</Reference>
<FillerTags>Filler</FillerTags>
<entity>
<entityName>ABC</entityName>
<entityId>012345</entityId>
</entity>
<Items>
<Item>
<entityId>012345</entityId>
<FillerTagsAgain>Filler1</FillerTagsAgain>
<FillerTagsAgain>Filler1</FillerTagsAgain>
<FillerTagsAgain>Filler1</FillerTagsAgain>
</Item>
<AnotherItem>
<entityId>012345</entityId>
<FillerTagsAgain>Filler2</FillerTagsAgain>
<FillerTagsAgain>Filler2</FillerTagsAgain>
<FillerTagsAgain>Filler2</FillerTagsAgain>
</AnotherItem>
</Items>
</Results>
<Results>
<Reference>{REFERENCE-HERE}</Reference>
<FillerTags>Filler</FillerTags>
<entity>
<entityName>DEF</entityName>
<entityId>54321</entityId>
</entity>
<Items>
<Item>
<entityId>54321</entityId>
<FillerTagsAgain>Filler1</FillerTagsAgain>
<FillerTagsAgain>Filler1</FillerTagsAgain>
<FillerTagsAgain>Filler1</FillerTagsAgain>
</Item>
<AnotherItem>
<entityId>54321</entityId>
<FillerTagsAgain>Filler2</FillerTagsAgain>
<FillerTagsAgain>Filler2</FillerTagsAgain>
<FillerTagsAgain>Filler2</FillerTagsAgain>
</AnotherItem>
</Items>
</Results>
</root>
{REFERENCE-HERE}
填料
基础知识
012345
012345
填充物1
填充物1
填充物1
012345
填充物2
填充物2
填充物2
{REFERENCE-HERE}
填料
DEF
54321
54321
填充物1
填充物1
填充物1
54321
填充物2
填充物2
填充物2
我可以告诉您这个答案吗:我是否可以建议您添加一些标签,以便人们可以轻松找到您的标签question@stormCloud谢谢,这看起来很有用。我之所以标记xml,是因为我不确定还有什么与标记相关。@stormCloud我已经阅读了答案,但不确定如何将该答案应用于我目前的情况。您能详细说明一下吗?加载xml文档后,您可以执行doc.selectNode(“/Results/entity/entityName”).text之类的操作来获取特定节点的值。当我说要添加一些标记时,我的意思是要包括您正在使用的语言(我假设是vb6?)。一旦您包括您正在使用的语言,您将让所有了解该语言的人都查看它:)@stormCloud这很有意义,我应该考虑到这一点。谢谢
Option Explicit
Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Sub ParseResults()
'Requires reference to Microsoft XML, v6.0
'Requires referenc to Microsoft Scripting Runtime
Dim xmlFilePath$, newFilePath$
Dim DOM As MSXML2.DOMDocument
Dim Customer As IXMLDOMNode
Dim fso As Scripting.FileSystemObject
'# Define the file you are going to load as XML
xmlFilePath = "C:\FAKEPATH\Final_Test.xml"
'# Define an output path for where to put the modified XML
newFilePath = "C:\FAKEPATH\Final_Test1.xml"
'# Create our DOM object
Set DOM = CreateObject("MSXML2.DOMDocument.6.0")
'# Load the XML file
DOM.Load xmlFilePath
'# Wait until the Document has loaded
Do
Sleep 250
Loop Until DOM.readyState = 4
'# Get the entityID node
Set Customer = DOM.DocumentElement.getElementsByTagName("CustomerId")(0)
'# Call a subroutine to append the entity to "Item" tags
AppendCustomer DOM, "Transaction", Customer
'## Create an FSO to write the new file
Set fso = CreateObject("Scripting.FileSystemObject")
'## Attempt to write the new/modified XML to file
On Error Resume Next
'MsgBox DOM.XML
fso.CreateTextFile(newFilePath, True, False).Write DOM.XML
If Err Then
'## Print the new XML in the Immediate window
Debug.Print DOM.XML
MsgBox "Unable to write to " & newFilePath & " please review XML in the Immediate window in VBE.", vbInformation
Err.Clear
End If
On Error GoTo 0
'Cleanup
Set DOM = Nothing
Set fso = Nothing
Set Customer = Nothing
End Sub
Sub AppendCustomer(DOM As Object, Transaction As String, copyNode As Object)
'## This subroutine will append child node to ALL XML Nodes matching specific string tag.
Dim itemColl As IXMLDOMNodeList
Dim itm As IXMLDOMNode
'# Get a collection of all elements matching the tagName
Set itemColl = DOM.DocumentElement.getElementsByTagName(Transaction)
'# Iterate over the collection, appending the copied node
For Each itm In itemColl
If itm.HasChildNodes Then
'# Insert this node before the first child node of Item
itm.InsertBefore copyNode.CloneNode(True), itm.FirstChild
Else
'# Append this node to the Item
itm.appendChild copyNode.CloneNode(True)
End If
Next
Set itm = Nothing
Set itemColl = Nothing
End Sub
'## Create an FSO to write the new file'
Set fso = CreateObject("Scripting.FileSystemObject")
Dim FF As Integer
FF = FreeFile
'## Attempt to write the new/modified XML to file'
fso.CreateTextFile newFilePath
Open newFilePath For Output As FF
Print #FF, dom.XML
Close #FF
fso.CreateTextFile(newFilePath, True, False).Write DOM.XML
'##### NO LONGER USED:'
'# Get the entityID node'
'Set Customer = DOM.DocumentElement.getElementsByTagName("CustomerId")(0)'
Dim itm As IXMLDOMNode
'# Instead of getting the first item like we did before, we can iterate the collection'
' of nodes with the entityID tag like so:'
For Each Customer In DOM.DocumentElement.getElementsByTagName("entityId")
'Since Item is Entity nextSibling, and Entity is parent of entityId,'
' we can iterate the collection if its childNodes like this:'
For Each itm In Customer.ParentNode.NextSibling.ChildNodes
If itm.HasChildNodes Then
'# Insert this node before the first child node of Item'
itm.InsertBefore Customer.CloneNode(True), itm.FirstChild
Else
'# Append this node to the Item'
itm.appendChild Customer.CloneNode(True)
End If
Next
Next
'##### This function call is no longer needed
'AppendCustomer DOM, "Transaction", Customer'
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Results>
<Reference>{REFERENCE-HERE}</Reference>
<FillerTags>Filler</FillerTags>
<entity>
<entityName>ABC</entityName>
<entityId>012345</entityId>
</entity>
<Items>
<Item>
<entityId>012345</entityId>
<FillerTagsAgain>Filler1</FillerTagsAgain>
<FillerTagsAgain>Filler1</FillerTagsAgain>
<FillerTagsAgain>Filler1</FillerTagsAgain>
</Item>
<AnotherItem>
<entityId>012345</entityId>
<FillerTagsAgain>Filler2</FillerTagsAgain>
<FillerTagsAgain>Filler2</FillerTagsAgain>
<FillerTagsAgain>Filler2</FillerTagsAgain>
</AnotherItem>
</Items>
</Results>
<Results>
<Reference>{REFERENCE-HERE}</Reference>
<FillerTags>Filler</FillerTags>
<entity>
<entityName>DEF</entityName>
<entityId>54321</entityId>
</entity>
<Items>
<Item>
<entityId>54321</entityId>
<FillerTagsAgain>Filler1</FillerTagsAgain>
<FillerTagsAgain>Filler1</FillerTagsAgain>
<FillerTagsAgain>Filler1</FillerTagsAgain>
</Item>
<AnotherItem>
<entityId>54321</entityId>
<FillerTagsAgain>Filler2</FillerTagsAgain>
<FillerTagsAgain>Filler2</FillerTagsAgain>
<FillerTagsAgain>Filler2</FillerTagsAgain>
</AnotherItem>
</Items>
</Results>
</root>