给出以下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
答案 0 :(得分: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
答案 1 :(得分:0)
由于'常见'lib在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