如何使用VBScript对XML中的节点进行分组

时间:2017-09-06 18:27:42

标签: xml xpath vbscript

我有这个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>

我希望将具有相同值的<c>元素分组到另一个父节点<d>下。所以输出应该是这样的:

<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

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

1 个答案:

答案 0 :(得分:0)

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

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操作,效率会更高。