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 式は、XML ツリー内の任意の場所からノード//FunctionalLibraryを選択します。直接の子ノードで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 に答える