You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在VBA生成XML时检索并编辑已存在的同名Section节点

解决VBA生成XML时非连续同名Section节点的追加问题

我看到你遇到的问题了——当前代码只能处理连续的同名Section行,非连续的同名项会重复创建节点,而且XPath查询失败是因为XML默认命名空间的问题,这是VBA操作带命名空间XML的常见坑。下面给你一步步解决的方案:

1. 关键问题:XML命名空间的XPath查询

你的XML使用了默认命名空间urn:Riwo.Pcs.Localization,直接用//Section这种XPath是找不到节点的——DOMDocument不知道这个前缀对应的命名空间。需要先给命名空间绑定一个前缀(比如ns),再用前缀来写XPath。

2. 修改后的完整代码

Sub RPCTranslatesCombinedInfoBackwardsChecking()
    Set oXMLDoc = CreateObject("MSXML2.DOMDocument.6.0") '用6.0版本更稳定,支持命名空间处理
    oXMLDoc.SetProperty "SelectionNamespaces", "xmlns:ns='urn:Riwo.Pcs.Localization'" '绑定命名空间前缀
    oXMLDoc.SetProperty "SelectionLanguage", "XPath" '指定用XPath查询
    oXMLDoc.async = False '同步处理,确保节点创建后立即能查询到

    '创建XML声明
    Set oPI = oXMLDoc.createProcessingInstruction("xml", "version=""1.0"" encoding=""UTF-8""")
    '创建根节点及属性
    Set oRoot = oXMLDoc.CreateNode(1, "Translations", "urn:Riwo.Pcs.Localization")
    With oRoot
        .SetAttribute "xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance"
        .SetAttribute "xmlns:xsd", "http://www.w3.org/2001/XMLSchema"
        .SetAttribute "code", "nl"
        .SetAttribute "description", "Dutch"
    End With
    oXMLDoc.AppendChild oRoot
    oXMLDoc.InsertBefore oPI, oXMLDoc.ChildNodes.Item(0)

    With ActiveSheet
        lRow = 2 '从第2行开始处理
        Do While .Cells(lRow, 4).Value <> ""
            sLineName = .Cells(lRow, 1).Value
            sSectionPrefix = Right(sLineName, Len(sLineName) - 1)
            sSectionName = .Cells(lRow, 4).Value
            Dim fullSectionName As String
            fullSectionName = sSectionPrefix & "." & sSectionName '构建完整的Section name属性值

            '1. 先查询是否已存在该Section节点
            Dim xPathQuery As String
            xPathQuery = "//ns:Section[@name='" & fullSectionName & "']" '用绑定的前缀ns来查询
            Set oElmSection = oXMLDoc.SelectSingleNode(xPathQuery)

            If oElmSection Is Nothing Then
                '2. 不存在则新建Section节点
                Set oElmSection = oXMLDoc.CreateNode(1, "Section", "urn:Riwo.Pcs.Localization")
                oElmSection.SetAttribute "name", fullSectionName
                oXMLDoc.DocumentElement.AppendChild oElmSection

                '新建对应的Translation节点(key=Info)
                Set oElmTranslation = oXMLDoc.CreateNode(1, "Translation", "urn:Riwo.Pcs.Localization")
                oElmTranslation.SetAttribute "key", "Info"
                oElmSection.AppendChild oElmTranslation
            Else
                '3. 存在则找到对应的Translation节点
                Set oElmTranslation = oElmSection.SelectSingleNode("ns:Translation[@key='Info']")
            End If

            '处理当前行的内容,拼接成要追加的文本
            sInfoDescription_1 = .Cells(lRow, 1).Value
            sInfoDescription_2 = .Cells(lRow, 2).Value
            sInfoDescription_3 = .Cells(lRow, 3).Value
            sInfoDescription_5 = .Cells(lRow, 5).Value
            Dim sInfo As String
            '如果是该Section的第一条记录,直接拼接;否则加<br/>分隔
            If oElmTranslation.Text = "" Then
                sInfo = sInfoDescription_1 & sInfoDescription_2 & sInfoDescription_3 & " " & sInfoDescription_5
            Else
                sInfo = " <br/> " & sInfoDescription_1 & sInfoDescription_2 & sInfoDescription_3 & " " & sInfoDescription_5
            End If

            '追加文本到Translation节点
            oElmTranslation.AppendChild oXMLDoc.createTextNode(sInfo)
            lRow = lRow + 1
        Loop
    End With

    MsgBox oXMLDoc.XML
    oXMLDoc.Save "C:\Users\thomas.RIWO\Desktop\Translations\RPC test\test2.xml"
End Sub

3. 核心改进点说明

  • 命名空间处理:通过SetProperty "SelectionNamespaces"绑定前缀,XPath查询时必须带上前缀(比如ns:Section),这样才能正确匹配到带默认命名空间的节点。
  • 先查询再创建:每次处理行时,先通过SelectSingleNode查询是否已存在对应name的Section节点,避免重复创建。
  • 灵活追加内容:判断Translation节点的文本是否为空,来决定是直接写入还是加<br/>分隔后追加,不管行是否连续都能正确合并内容。
  • 使用稳定的DOM版本:改用MSXML2.DOMDocument.6.0,比早期版本对XPath和命名空间的支持更完善。

内容的提问来源于stack exchange,提问作者thordijk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:59:37