0

我正在做一个项目,我需要解析一个 XML 文件并在 100 个不同的 XML 路径/节点上执行完全相同的代码。我的代码目前看起来像这样……</p>

def items = parser.parseText(inputFile.text)

items.item.each { item ->
    try {
        // do stuff with item.some_node
    } catch(Exception ex) {
        //exception stuff
    }
    try {
        // do stuff with item.weight_node
    } catch(Exception ex) {
        //exception stuff
    }
    try {
        // do stuff with item.another_node[3].sub_node
    } catch(Exception ex) {
        //exception stuff
    }
    try {
        // do stuff with item.some_node
    } catch(Exception ex) {
        //exception stuff
    }
    // do this a 100 times or so with other item node paths
}

由于“要做的事情”和异常的“事情”每次都完全相同,唯一改变的是我正在使用的节点。因此,我宁愿将节点表达式发送到方法或像这样扩展节点类......</p>

def myMethod(currentNode) {
    try {
        // do stuff
    } catch(Exception ex) {
        //exception stuff
    }
}

items.item.each { item ->
    myMethod(item.some_node)
    myMethod(item.weight_node)
    myMethod(item.another_node[3].sub_node)
    myMethod(item.some_node)
}

// OR

def myProcess(NodeList n){
    try {
        // do stuff
    } catch(Exception ex) {
        //exception stuff
    }
}
NodeList.metaClass.myProcess = { -> myProcess(delegate) }

items.item.each { item ->
    item.some_node.myMethod()
    item.weight_node.myMethod()
    item.another_node[3].sub_node.myMethod()
    item.some_node.myMethod()
}

通过方法尝试,我无法弄清楚如何将 XPath 传递给该方法然后使用它。使用类扩展方法,只要节点实际存在,它就可以工作。如果没有,我在尝试调用 myProcess 时会出错。

有任何想法吗?

4

2 回答 2

0

对于第二种情况

NodeList.metaClass.myProcess = { -> myProcess(delegate) }

items.item.each { item ->
    item.some_node.myMethod()
    item.weight_node.myMethod()
    ...
}

您可以使用 null 安全访问器来避免不存在的节点上的异常:

items.item.each { item ->
    item?.some_node?.myMethod()
    item?.weight_node?.myMethod()
    ...
}
于 2017-06-06T06:15:39.033 回答
0

由于没有 xml,所以取一个 xml 样本。

您确实需要像最初提到的那样为每个节点编写。

在 groovy 中,这很容易使用find(返回单个值)或findAll(多个值)来实现。请看下面的例子。

def jdbcResponse = """<Results>
    <ResultSet fetchSize="10">
        <Row rowNumber="1">
            <T1>TEXT1</T1>
            <T2>TASK1</T2>
            <T3>Value1</T3>
            <T4>xyz</T4>
      </Row>
       <Row rowNumber="2">
            <T1>TEXT2</T1>
            <T2>TASK2</T2>
            <T3>Value1a</T3>
            <T4>ABC</T4>
      </Row>
     </ResultSet>
</Results>"""

def xml = new XmlSlurper().parseText(jdbcResponse)

//Return the matching element
def getData = { elementName ->
    xml.'**'.findAll{it.name() == elementName}
}

//Coerced result to List of string as T1/2 is not complex
def t1s = getData('T1') as List<String>
def t2s = getData('T2') as List<String>
println t1s

//Here you get Rows which is complex, so not coerced
def rows = getData('Row')
//Check if first row T1 is TEXT1
assert rows[0].T1.text() == 'TEXT1'
于 2017-06-06T02:01:00.543 回答