0

给定以下 XML

<Tests>
    <AutomatedTests>
        <TestName>Test1</TestName>
        <FunctionalLibraries>
            <FunctionalLibrary>CommonLib</FunctionalLibrary>
            <FunctionalLibrary>AppTestLib</FunctionalLibrary>
            <FunctionalLibrary>Test1Lib</FunctionalLibrary>
        </FunctionalLibraries>
    </AutomatedTests>
    <AutomatedTests>
        <TestName>Test2</TestName>
        <FunctionalLibraries>
            <FunctionalLibrary>CommonLib</FunctionalLibrary>
            <FunctionalLibrary>AppTestLib</FunctionalLibrary>
            <FunctionalLibrary>Test2Lib</FunctionalLibrary>
        </FunctionalLibraries>
    </AutomatedTests>
    <AutomatedTests>
        <TestName>Test3</TestName>
        <FunctionalLibraries>
            <FunctionalLibrary>CommonLib</FunctionalLibrary>
            <FunctionalLibrary>Test3Lib</FunctionalLibrary>
        </FunctionalLibraries>
    </AutomatedTests>
</Tests>

使用 VBScript,我如何找到所有 /Tests/AutomatedTests 节点共有的所有 /Tests/AutomatedTests/FunctionalLibraries 节点。
根据上面的xml,结果应该是...

<CommonTestLibraries>
    <FunctionalLibrary>CommonLib</FunctionalLibrary>
</CommonTestLibraries>

谢谢

这就是我所拥有的,我希望有一种更简单的方法,因为我必须在同一个文件上多次执行此操作。

set tempDict = CreateObject("Scripting.Dictionary")
set commonDict = CreateObject("Scripting.Dictionary")

Set xmlDoc = CreateObject("Microsoft.XMLDOM")
xmlDoc.Load(fileName)
set testNodes = xmlDoc.SelectNodes("/Tests/AutomatedTests")
isFirst = true

for each testNode in testNodes
    set functionalLibraryNodes = testNode.SelectNodes("FunctionLibraries/FunctionLibrary")
    For Each functionalLibraryNode in functionalLibraryNodes
       If not tempDict.Exists(functionalLibraryNode.Text) Then
            tempDict.Add functionalLibraryNode.Text, functionalLibraryNode.Text
       End If
    Next
    If NOT isFirst Then
        for each item in commonDict
            if tempDict.Exists(item) = false Then
                commonDict.Remove item
            End If
        Next
    Else
        Set commonDict = tempDict
        isFirst = false
    End If

    Set tempDict = nothing
    Set tempDict = CreateObject("Scripting.Dictionary")
Next
4

2 回答 2

1

我可能会做这样的事情:

filename = "C:\path\to\your.xml"

Set xmlDoc = CreateObject("Msxml2.DOMDocument.6.0")
xmlDoc.async = False
xmlDoc.load filename

If xmlDoc.parseError <> 0 Then
  WScript.Echo xmlDoc.parseError.reason
  WScript.Quit xmlDoc.parseError
End If

'determine the total number of tests
numTests = xmlDoc.selectNodes("/Tests/AutomatedTests").length

'count the libraries from all tests
Set commonDict = CreateObject("Scripting.Dictionary")
For Each node In xmlDoc.selectNodes("//FunctionalLibrary")
  commonDict(node.text) = commonDict(node.text) + 1
Next

'libraries common to all tests must have occurred {numTests} number of times
For Each lib In commonDict.Keys
  If commonDict(lib) = numTests Then WScript.Echo commonDict(lib)
Next

不过,可能有更有效的方法。

注意:线

commonDict(node.text) = commonDict(node.text) + 1

利用表达式dict(key)自动将不存在的键添加到字典并用空值初始化它的事实。然后在加法中将该空值强制转换为 0。具有相同语义的显式代码如下所示:

If Not commonDict.Exists(node.text) Then
  commonDict(node.text) = 0
Else
  commonDict(node.text) = commonDict(node.text) + 1
End If

注意: XPath 表达式//FunctionalLibrary将从 XML 树中的任何位置选择FunctionalLibrary节点。如果您有任何不是直接子节点的此类节点/Tests/AutomatedTests/FunctionalLibraries(您提供的示例数据表明您没有),您应该明确 XPath 表达式:

funclib = "/Tests/AutomatedTests/FunctionalLibraries/FunctionalLibrary"
For Each node In xmlDoc.selectNodes(funclib)
  commonDict(node.text) = commonDict(node.text) + 1
Next
于 2013-10-14T17:15:59.967 回答
0

由于“通用”库在 n 次测试中出现 n 次,因此字典方法可以简单得多:

  Dim oFS    : Set oFS  = CreateObject("Scripting.FileSystemObject")
  Dim sFSpec : sFSpec   = oFS.GetAbsolutePathName("..\data\02.xml")
  Dim oXML   : Set oXML = CreateObject("Msxml2.DOMDocument.6.0")
  oXML.load sFSpec
  If 0 = oXML.parseError Then
     Dim sXPath : sXPath     = "/Tests/AutomatedTests/FunctionalLibraries/FunctionalLibrary"
     Dim ndlFnd : Set ndlFnd = oXML.selectNodes(sXPath)
     If 0 = ndlFnd.length Then
        WScript.Echo sXPath, "not found"
     Else
        Dim dicLibs  : Set dicLibs  = CreateObject("Scripting.Dictionary")
        Dim nTests   : nTests       = ndlFnd(0).parentNode.parentNode.parentNode.childNodes.length
        WScript.Echo nTests, "tests"
        Dim ndFnd, sLib
        For Each ndFnd In ndlFnd
            sLib  = ndFnd.text
            dicLibs(sLib) = dicLibs(sLib) + 1
        Next
        For Each sLib In dicLibs.Keys()
            If dicLibs(sLib) = nTests Then
               WScript.Echo sLib, dicLibs(sLib)
            End If
        Next
     End If
  Else
     WScript.Echo oXML.parseError.reason
  End If
于 2013-10-14T16:03:03.797 回答