我有一个问题,我似乎不能工作的方式过去,并希望你们中的一些知识丰富的马文可以提供一个解决方案。
我有一个包含序列的XSD文档。如您所知,这意味着所有元素都必须以指定的顺序显示。我需要使用它,因为其中一些也是可选的(minOccurs = "0")。
下面是模式的一个简化部分:
<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文档的相关部分:
<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>
...我需要做两件事:
如果存在元素,则更新其值
我已经能够在“结果”节点的末尾添加一个节点,但无法让find进行更新,也无法将节点插入到适当的位置以满足XSD。以下是代码:
...
//-- 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输出(注意,第一个结果的值被更新了,第二个结果被插入了--但是在正确的位置.还可以有其他元素):
<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>
...有人能告诉我怎么做吗?谢谢!标记
发布于 2011-08-11 14:20:03
好的,进展。幸运的是,我可以控制模式,因此我将“序列”更改为"all“。"all“允许0或1的"minOccurs”,因此我可以这样处理可选的。我将可能多次发生的一个元素重构为包含可以重复的元素的一个可选元素。
因为"all“允许任何订单(和可选的),所以我可以在任何地方添加,比如追加到末尾。
至于找出现有的,这是可行的:
codeNode.children().find { it.name() == "resultReporter" }我对这段代码的结果进行"isEmpty()“测试,以确定它是否真的存在。
所以:不是一个通用的解决方案(例如,如果我不能更改XSD),而是可以满足我的需要。希望这对其他人有帮助。
如果一般人知道如何解决这个问题,请大声说出来!
为了给出完整的解决方案,下面是修改XML的代码:
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())
}
}
}https://stackoverflow.com/questions/7016314
复制相似问题