Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
XML文件输出仅显示字节顺序标记_Xml_Vba_Dom_Byte Order Mark - Fatal编程技术网

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

我有一个试图解析的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>
  <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>