У меня возникла проблема, которую я, кажется, не могу преодолеть, и надеюсь, что некоторые из вас, знающих женщин, смогут найти решение.
У меня есть документ с 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>
...
Мне нужно уметь делать две вещи:
- Если элемент существует, обновите его значение. Например. измените значение inputEmployeeId на «EntVal» для resultCode «005009». Для этого необходимо найти, существует ли этот элемент.
- Если элемент не существует, добавьте его в место, которое пройдет проверку в соответствии со схемой. Например. добавьте resultReporter и введитеEmployeeId для resultCode "005025". Обратите внимание, что существуют дополнительные элементы, которые могут присутствовать или не присутствовать, как показано в приведенном выше фрагменте XML.
Мне удалось добавить узел в конец «результирующего» узла, но я не могу найти найти работу для обновления или вставить узел в нужное место, чтобы удовлетворить 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>
...
Итак: кто-нибудь может сказать мне, как заставить это работать? Спасибо! Mark