【问题标题】:How to group nodes in XML using VBScript如何使用 VBScript 对 XML 中的节点进行分组
【发布时间】:2017-09-06 18:27:42
【问题描述】:

我有这个 XML 文件:

<root>
 <a>
  <b>
   <c>1</c>
   <c>2</c>
   <c>1</c>
   <c>4</c>
  </b>
 </a>
<a>
 <b>
   <c>1</c>
   <c>2</c>
   <c>2</c>
   <c>3</c>
 </b>
</a>
</root>

我想将具有相同值的&lt;c&gt; 元素分组到另一个父节点&lt;d&gt; 下。所以输出应该是这样的:

<root>
<a>
    <b>
        <d>
            <c>1</c>
            <c>1</c>
        </d>
        <d>
            <c>2</c>
        </d>
        <d>
            <c>4</c>
        </d>
    </b>
</a>
<a>
    <b>
        <d>
            <c>1</c>
        </d>
        <d>
            <c>2</c>
            <c>2</c>
        </d>
        <d>
            <c>3</c>
        </d>
    </b>
</a>

我已经开始使用这段代码,但我只设法创建到父级。

'Create initial DOM
Set oXML = CreateObject("msxml2.DOMDocument.6.0")
oXML.Async = False
parInputXML = "<root>  <a>   <b>    <c>1</c>    <c>2</c>    <c>1</c>       <c>4</c>   </b>  </a> <a>  <b>    <c>1</c>    <c>2</c>    <c>2</c>    <c>3</c>  </b> </a> </root>"
oXML.LoadXML(parInputXML)

'Loop through nodes
For Each bNode In oXML.SelectNodes("/root/a/b")
    For Each cNode In bNode.SelectNodes("./c")
        'Add new node Spec
        Set dNode = oXML.CreateElement("d")
        bNode.AppendChild dNode
        dNode.AppendChild cNode

        'Add the cloned node
        'Set tempChildNode = cNode.CloneNode(True)
        'dNode.AppendChild tempChild

        'Remove the old node
        'cNode.ParentNode.RemoveChild(cNode)
    Next
Next
MsgBox oXML.Xml

有人知道我可以如何将它们分组吗?我需要一个额外的循环吗?

【问题讨论】:

    标签: xml xpath vbscript


    【解决方案1】:

    您可以尝试以下代码并根据您的要求对其进行自定义,因为我没有专注于错误处理。

    REM ===========================================================================
    REM you can read xml from string or a file here - change as per your requirement
    REM ===========================================================================
    
    Set objXML = CreateObject("MSXML2.DOMDocument.6.0")
    With objXML
        .SetProperty "SelectionLanguage", "XPath"
        .ValidateOnParse = True
        .Async = False
        .Load "C:\Users\pankaj.jaju\Desktop\xmltest.xml"
    End With
    
    REM ===========================================================================
    REM read all b nodes
    REM store the c nodes for each b node in a .net sorted array
    REM delete all c node for a b node
    REM create d nodes based on sorted array's length
    REM create new c nodes and get the values from sorted array
    REM ===========================================================================
    
    Set nodesB = objXML.DocumentElement.SelectNodes("//b")
    For Each nodeB In nodesB
        Set nodesC = nodeB.SelectNodes("c")
        Set objList = CreateObject("System.Collections.Sortedlist")
        For Each nodeC In nodesC
            If objList.ContainsKey(nodeC.Text) Then 'if we have a duplicate value for a c node - e.g. 2 c nodes with value 1 and 2
                objList(nodeC.Text) = objList(nodeC.Text) + 1 'if key already exist, then increment with one to know how many node c to create later
            Else
                objList.Add nodeC.Text, 1
            End If
            nodeB.RemoveChild nodeC
        Next
    
        objList.TrimToSize
        For i = 0 To objList.Count - 1
            Set nodeD = objXML.CreateElement("d")
            nodeB.AppendChild nodeD
            For j = 1 To objList(objList.GetKey(i))
                Set nodeNewC = objXML.CreateElement("c")
                nodeD.AppendChild nodeNewC
                nodeNewC.Text = objList.GetKey(i)
            Next
        Next
    Next
    
    MsgBox objXML.XML
    

    希望这会有所帮助。

    PS - 我会尝试通过 xslt 解决这种类型的 xml 操作,这样会更有效。

    【讨论】:

    • @Operagust - 6 个月后您为什么不接受这个?
    猜你喜欢
    • 1970-01-01
    • 2023-01-24
    • 2021-03-14
    • 2021-11-17
    • 1970-01-01
    • 1970-01-01
    • 2015-05-17
    • 2012-08-07
    相关资源
    最近更新 更多