我有以下xml文件:
<testItems>
<children>
<testItem name=TestSuite1 enabled=false>
<children>
<testItem name=test1 enabled=false>
</testItem>
<testItem name=test2 enabled=false>
</testItem>
<testItem name=test3 enabled=false>
</testItem>
</children>
</testItem>
<testItem name=TestSuite2 enabled=false>
<children>
<testItem name=test3 enabled=false>
</testItem>
<testItem name=test4 enabled=false>
</testItem>
<testItem name=test5 enabled=false>
</testItem>
</children>
</testItem>
结构可以改变(意味着树的深度可以改变)。
我想启用TestSuite1并以递归方式启用TestSuite1的所有子项(test1,test2,test3)
到目前为止,我有:
def root = new XmlParser(false, false, true).parse(mdsFile)
root.depthFirst().each {
if (it.@name == testItemToEnable) {
it.@enabled = true
it.children.depthFirst().each { child ->
child.@enabled = true
}
}
但我有以下例外:
No signature of method: groovy.util.NodeList.depthFirst() is applicable for argument types: () values: []
[评论中的问题后补充]
<testItems>
<children>
<testItem name="TestSuite1" enabled="false">
<children>
<testItem name="test1" enabled="false">
</testItem>
<testItem name="test2" enabled="false">
<children>
<testItem name="testX" enabled="false">
</testItem>
</children>
</testItem>
<testItem name="test3" enabled="false">
</testItem>
</children>
</testItem>
<testItem name="TestSuite2" enabled="false">
<children>
<testItem name="test3" enabled="false">
</testItem>
<testItem name="test4" enabled="false">
</testItem>
<testItem name="test5" enabled="false">
</testItem>
</children>
</testItem>
方案: 1. suiteToEnable ='test1'=&gt; test1,TestSuite1变为true
答案 0 :(得分:1)
[澄清评论后修改]
以下代码将enabled属性设置为true并打印出结果字符串:
import groovy.xml.*
def str = '''\
<testItems>
<children>
<testItem name="TestSuite1" enabled="false">
<children>
<testItem name="test1" enabled="false">
</testItem>
<testItem name="test2" enabled="false">
</testItem>
<testItem name="test3" enabled="false">
</testItem>
</children>
</testItem>
<testItem name="TestSuite2" enabled="false">
<children>
<testItem name="test3" enabled="false">
</testItem>
<testItem name="test4" enabled="false">
</testItem>
<testItem name="test5" enabled="false">
</testItem>
</children>
</testItem>
</children>
</testItems>'''
def xml = new XmlSlurper().parseText(str)
def suiteToEnable = 'TestSuite2'
xml.'**'.find {
it.name() == 'testItem' && it.@name == suiteToEnable
}.'**'.findAll {
it.name() == 'testItem'
}*.@enabled = 'true'
println XmlUtil.serialize(xml)
输出:
<?xml version="1.0" encoding="UTF-8"?><testItems>
<children>
<testItem name="TestSuite1" enabled="false">
<children>
<testItem name="test1" enabled="false"/>
<testItem name="test2" enabled="false"/>
<testItem name="test3" enabled="false"/>
</children>
</testItem>
<testItem name="TestSuite2" enabled="true">
<children>
<testItem name="test3" enabled="true"/>
<testItem name="test4" enabled="true"/>
<testItem name="test5" enabled="true"/>
</children>
</testItem>
</children>
</testItems>
这使用了常规depthFirst alias **和spread operator *.
。
[评论中提问后的补遗]
关于我们可以做的第二个问题,即只启用一个孩子及其祖父母:
def xml = new XmlSlurper().parseText(str)
def suiteToEnable = 'test2'
def item = xml.'**'.find {
it.name() == 'testItem' && it.@name == suiteToEnable
}
item.@enabled = 'true'
item.parent().parent().@enabled = 'true'
println XmlUtil.serialize(xml)
打印:
<?xml version="1.0" encoding="UTF-8"?><testItems>
<children>
<testItem name="TestSuite1" enabled="true">
<children>
<testItem name="test1" enabled="false"/>
<testItem name="test2" enabled="true"/>
<testItem name="test3" enabled="false"/>
</children>
</testItem>
<testItem name="TestSuite2" enabled="false">
<children>
<testItem name="test3" enabled="false"/>
<testItem name="test4" enabled="false"/>
<testItem name="test5" enabled="false"/>
</children>
</testItem>
</children>
</testItems>
[评论中的另一个问题附录2]
以下代码首先找到一个特定节点,然后将所有父节点的元素名称testItem
设置为enabled="true"
:
def xml = new XmlSlurper().parseText(str)
def suiteToEnable = 'testX'
// first find our target node
def item = xml.'**'.find {
it.name() == 'testItem' && it.@name == suiteToEnable
}
// then get the parents recursively, find all parents called
// 'testItem' and set them to enabled = 'true'
getParents(item).findAll { it.name() == 'testItem' }.each {
it.@enabled = 'true'
}
println XmlUtil.serialize(xml)
// recursively get parents of node using the '..' alias for
// the node.parent() call
def getParents(node) {
(node.is(node.'..') ? [] : getParents(node.'..')) + [node]
}
打印出来:
<testItems>
<children>
<testItem name="TestSuite1" enabled="true">
<children>
<testItem name="test1" enabled="false"/>
<testItem name="test2" enabled="true">
<children>
<testItem name="testX" enabled="true"/>
</children>
</testItem>
<testItem name="test3" enabled="false"/>
</children>
</testItem>
<testItem name="TestSuite2" enabled="false">
<children>
<testItem name="test3" enabled="false"/>
<testItem name="test4" enabled="false"/>
<testItem name="test5" enabled="false"/>
</children>
</testItem>
</children>
</testItems>