使用 Excel VBA 编辑 XML DOM 的所有文本节点

Editing All Text Nodes of XML DOM using Excel VBA

我正在尝试使用 Excel VBA 编辑 XML DOM 文件,但面临超出 1 级节点的问题。 我的要求是修改所有(且仅)文本节点,但我编写的脚本修改了所有级别 1 节点。

请提出修改代码的建议。

输入XML:

<?xml version="1.0" encoding="UTF-8"?>
<Envelope>
    <Body>
        <Request>
            <individual>
                <hasName>
                    <firstName>ABC</firstName>
                    <lastName>DEF</lastName>
                </hasName>
                <birthDate>2015-01-10</birthDate>
                <hasContact>
                    <type>Mobile</type>
                    <phoneAddress>
                        <countryCode>02</countryCode>
                        <localNumber>12345678</localNumber>
                    </phoneAddress>
                </hasContact>
            </individual>
        </Request>
    </Body>
</Envelope>

Excel VB 脚本:

Option Explicit
Sub Test()
Dim xmlDoc
Dim colNodes
Dim objNode
Dim objNodesParam

Set xmlDoc = CreateObject ("Microsoft.XMLDOM")
xmlDoc.Async = "False"
xmlDoc.Load("H:\Desktop\Request.xml")
Set colNodes = xmlDoc.SelectNodes ("/Envelope/Body/Request/individual/*")

For Each objNode In colNodes
objNodeParam = "{{" & objNode.nodeName & "}}"
objNode.Text = objNodeParam
Next

xmlDoc.Save "H:\Desktop\Request.xml"

End Sub

以上脚本的实际输出:

  <?xml version="1.0" encoding="UTF-8"?>
  <Envelope>
    <Body>
        <Request>
            <individual>
                <hasName>{{hasName}}</hasName>
                <birthDate>{{birthDate}}</birthDate>
                <hasContact>{{hasContact}}</hasContact>
            </individual>
        </Request>
    </Body>
</Envelope>

预期输出:

<?xml version="1.0" encoding="UTF-8"?>
<Envelope>
    <Body>
        <Request>
            <individual>
                <hasName>
                    <firstName>{{firstName}}</firstName>
                    <lastName>{{lastName}}</lastName>
                </hasName>
                <birthDate>{{birthDate}}</birthDate>
                <hasContact>
                    <type>{{type}}</type>
                    <phoneAddress>
                        <countryCode>{{countryCode}}</countryCode>
                        <localNumber>{{localNumber}}</localNumber>
                    </phoneAddress>
                </hasContact>
            </individual>
        </Request>
    </Body>
</Envelope>

背景见here。你需要一个递归方法:

Option Explicit

Dim oFS    : Set oFS  = CreateObject("Scripting.FileSystemObject")
Dim sFSpec : sFSpec   = oFS.GetAbsolutePathName("..\data921005.xml")
Dim oXML   : Set oXML = CreateObject("Msxml2.DOMDocument.6.0")
oXML.load sFSpec
If 0 = oXML.parseError Then
   recursiveTraversal oXML.documentElement, 0
   WScript.Echo "==============="
   WScript.Echo oXML.xml
Else
   WScript.Echo objMSXML.parseError.reason
End If

Sub recursiveTraversal(oElm, nIndent)
  If oElm.nodeType = 3 Then
     WScript.Echo Space(nIndent), oElm.text
     oElm.text = "{{" & oElm.parentNode.tagName & "}}"
  Else
     WScript.Echo Space(nIndent), oElm.tagName
     If 0 < oElm.childNodes.length Then
        Dim oChild
        For Each oChild In oElm.childNodes
            recursiveTraversal oChild, nIndent + 2
        Next
     End If
  End If
End Sub

输出:

cscript 33921005.vbs
 Envelope
   Body
     Request
       individual
         hasName
           firstName
             ABC
           lastName
             DEF
         birthDate
           2015-01-10
         hasContact
           type
             Mobile
           phoneAddress
             countryCode
               02
             localNumber
               12345678
===============
<?xml version="1.0"?>
<Envelope>
        <Body>
                <Request>
                        <individual>
                                <hasName>
                                        <firstName>{{firstName}}</firstName>
                                        <lastName>{{lastName}}</lastName>
                                </hasName>
                                <birthDate>{{birthDate}}</birthDate>
                                <hasContact>
                                        <type>{{type}}</type>
                                        <phoneAddress>
                                                <countryCode>{{countryCode}}</countryCode>
                                                <localNumber>{{localNumber}}</localNumber>
                                        </phoneAddress>
                                </hasContact>
                        </individual>
                </Request>
        </Body>
</Envelope>