【问题标题】:Passing XML Paths and evaluating传递 XML 路径并评估
【发布时间】:2017-06-05 22:40:57
【问题描述】:

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

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
}

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

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 时会出错。

有什么想法吗?

【问题讨论】:

  • dscl,你试过解决办法吗?

标签: xml groovy gpath


【解决方案1】:

由于没有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'

【讨论】:

    【解决方案2】:

    第二种情况

    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()
        ...
    }
    

    【讨论】:

      猜你喜欢
      • 2020-11-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-10
      • 2013-10-20
      • 1970-01-01
      • 1970-01-01
      • 2019-12-15
      相关资源
      最近更新 更多