2

以下是一个示例 XML:

<root>
    <persons>
        <person gender="female">X</person>
        <person gender="female">Y</person>
        <person gender="male">Z</person>
    </persons>
</root> 

我想gender="male"通过使用 GPath 来获取元素计数。

我有以下代码:

def xml =
'''
    <root>
        <persons>
            <person gender="female">X</person>
            <person gender="female">Y</person>
            <person gender="male">Z</person>
        </persons>
    </root>    
'''

def slurper = new XmlSlurper()
def parsedText = slurper.parseText(xml)
def locator = 'persons.person[@gender="male"]'

def elements = Eval.x(parsedText, "x.${locator}")

println elements.size()

它给了我错误:

org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
Script1.groovy: 1: unexpected token: = @ line 1, column 25.
   x.persons.person[@gender="male"]
                           ^

1 error

该代码仅用于问题的演示目的。在实际情况下,我有一个实用方法,它接受 XML 和 GPath,如果给定 GPath 可以找到任何元素,则返回。

更新:1

以下是实际的实用方法,它将 xml 和定位器(GPath)作为参数并检查是否有任何元素的路径与提供的定位器匹配。

public static void verifyElementExists(String xml, String locator) throws NoElementFoundException {
    def slurper = new XmlSlurper()
    def parsedText = slurper.parseText(xml)
    def elements = Eval.x(parsedText, "x.${locator}")

    if(elements.size() == 0) {
        throw new NoElementFoundException()
    }
}
4

2 回答 2

3

不确定您要实现的确切用例。

如果您需要一个可以在某些元素或提供GPath的元素可用或不可用时返回的方法,可以通过以下方式实现:

解决方案确实没有太大变化。

而不是字符串作为定位器,用户需要传递与它相同的东西Closure并且它不使用Eval

//Method to find if element exists.
static def isElementExists (String xmlStr, Closure closure){
    def xml = new XmlSlurper().parseText(xmlStr)
    def elements = closure(xml)
    elements.size() ? true : false    
}

def xmlString = '''<root>
    <persons>
        <person gender="female">X</person>
        <person gender="female">Y</person>
        <person gender="male">Z</person>
    </persons>
</root>'''

//Call to the above method, use either of the way to make a call; both are same
//In the below example, the same string used as locator is being passed as Closre
println isElementExists(xmlString) {x -> x.'**'.findAll { it.name()=='person' && it.@gender == 'male' } }

或者

println isElementExists(xmlString, {x -> x.'**'.findAll { it.name()=='person' && it.@gender == 'male' } } )

如果您只想检查person元素是否存在,则可以按如下方式使用它:

println isElementExists(xmlString) {x -> x.persons.person }

您可以快速在线尝试demo

编辑:提高可读性或简化.

您甚至可以执行以下操作。当然,最后一个语句和下面的语句结果相同。

def locator = {x -> x.persons.person }
println isElementExists(xmlString, locator)
于 2017-12-15T14:33:51.550 回答
0

认为你需要

def locator = "persons.person.findAll { it.@gender == 'male' }"

如果可能的话,我会避免这种情况,使用Eval不是一条安全的步行路径

于 2017-12-09T14:10:55.533 回答