首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >与模式匹配的Groovy XMLSlurper更新文档

与模式匹配的Groovy XMLSlurper更新文档
EN

Stack Overflow用户
提问于 2011-08-10 19:06:28
回答 1查看 1K关注 0票数 0

我有一个问题,我似乎不能工作的方式过去,并希望你们中的一些知识丰富的马文可以提供一个解决方案。

我有一个包含序列的XSD文档。如您所知,这意味着所有元素都必须以指定的顺序显示。我需要使用它,因为其中一些也是可选的(minOccurs = "0")。

下面是模式的一个简化部分:

代码语言:javascript
复制
    <xs:element name="result">
    <xs:complexType>
        <xs:sequence>
            <xs:element ref="tns:resultCode"/>
            <xs:element ref="tns:resultAbbreviations" minOccurs="0"/>
            <xs:element ref="tns:resultReporter" minOccurs="0"/>
            <xs:element ref="tns:vendorData" minOccurs="0" maxOccurs="unbounded"/>
        </xs:sequence>
    </xs:complexType>
</xs:element>

XML文档的相关部分:

代码语言:javascript
复制
<lab:order>
  <lab:results>
     <lab:result>
        <lab:resultCode>005009</lab:resultCode>
        <lab:resultAbbreviations>
           <lab:resultAbbreviation>FOO</lab:resultAbbreviation>
        </lab:resultAbbreviations>
        <lab:resultReporter>
           <lab:enteredEmployeeId>86118</lab:enteredEmployeeId>
        </lab:resultReporter>
        <lab:vendorData value="123" key="ABC"/>
        <lab:vendorData value="ABC" key="123"/>
     </lab:result>
     <lab:result>
        <lab:resultCode>005025</lab:resultCode>
     </lab:result>
     ...

我需要做两件事:

如果存在元素,则更新其值

  1. 。例如,将enteredEmployeeId值更改为resultCode "005009“的"EntVal”。这需要查找该元素是否存在。如果某个元素不存在,则将其添加到根据架构通过验证的位置。
  2. 。例如,添加resultReporter和enteredEmployeeId表示resultCode "005025“。请注意,有一些可选的元素可能存在,也可能没有,如上面的XML片段所示。

我已经能够在“结果”节点的末尾添加一个节点,但无法让find进行更新,也无法将节点插入到适当的位置以满足XSD。以下是代码:

代码语言:javascript
复制
    ...
//-- ResultReporter: enteredEmployeeId, verifiedEmployeeId
// Must add to proper result, based on code
ResultReporter reporter = nextResult.getReporter();
NodeChild codeNode = getResultNodeFor( nextResult.getCode() );
if( codeNode != null ) {    //found proper result - does reporter exist already?
    def reporterNode = codeNode.find { it.name() == 'resultReporter' }
    if( !reporterNode.isEmpty() ) { //reporter node exists - update it
        reporterNode.'lab:enteredEmployeeId'( nextResult.getReporter().getEnteredEmployeeId() )
    } else {    //element does not exist - add new one
        codeNode.appendNode {
            'lab:resultReporter' {
                'lab:enteredEmployeeId'(nextResult.getReporter().getEnteredEmployeeId())
            }
        }
    }
} else {    //not found
    throw new IllegalArgumentException("Cannot add reporter for nonexistent result code: " + nextResult.getCode() );
}
...
    /**
 * @param aCode
 * @return the Node with resultCode = aCode, else null
 */
private NodeChild getResultNodeFor( String aCode ) {
    for( def nextResult : labDoc.order.results.children() ) {
        if(  nextResult.resultCode.text().equals(aCode) ) { //found
            return nextResult;
        }
    }
    return null;    //not found
}

我正在寻找像这样的XML输出(注意,第一个结果的值被更新了,第二个结果被插入了--但是在正确的位置.还可以有其他元素):

代码语言:javascript
复制
   <lab:order>
  <lab:results>
     <lab:result>
        <lab:resultCode>005009</lab:resultCode>
        <lab:resultAbbreviations>
           <lab:resultAbbreviation>FOO</lab:resultAbbreviation>
        </lab:resultAbbreviations>
        <lab:resultReporter>
           <lab:enteredEmployeeId>EntVal</lab:enteredEmployeeId>
        </lab:resultReporter>
        <lab:vendorData value="123" key="ABC"/>
        <lab:vendorData value="ABC" key="123"/>
     </lab:result>
     <lab:result>
        <lab:resultCode>005025</lab:resultCode>
        <lab:resultReporter>
           <lab:enteredEmployeeId>EntVal</lab:enteredEmployeeId>
        </lab:resultReporter>
     </lab:result>
     ...

有人能告诉我怎么做吗?谢谢!标记

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-08-11 14:20:03

好的,进展。幸运的是,我可以控制模式,因此我将“序列”更改为"all“。"all“允许0或1的"minOccurs”,因此我可以这样处理可选的。我将可能多次发生的一个元素重构为包含可以重复的元素的一个可选元素。

因为"all“允许任何订单(和可选的),所以我可以在任何地方添加,比如追加到末尾。

至于找出现有的,这是可行的:

代码语言:javascript
复制
codeNode.children().find { it.name() == "resultReporter" }

我对这段代码的结果进行"isEmpty()“测试,以确定它是否真的存在。

所以:不是一个通用的解决方案(例如,如果我不能更改XSD),而是可以满足我的需要。希望这对其他人有帮助。

如果一般人知道如何解决这个问题,请大声说出来!

为了给出完整的解决方案,下面是修改XML的代码:

代码语言:javascript
复制
    def reporterNode = codeNode.children().find { it.name() == "resultReporter" }
if( !reporterNode.isEmpty() ) { //reporter node exists - update it
    reporterNode.replaceNode { node ->
        'lab:resultReporter'() {
            'lab:enteredEmployeeId'(nextResult.getReporter().getEnteredEmployeeId())
        }
    }
} else {    //element does not exist - add new one
    codeNode.appendNode {
        'lab:resultReporter' {
            'lab:enteredEmployeeId'(nextResult.getReporter().getEnteredEmployeeId())
        }
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7016314

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档