わかりました、簡単な方法はfragmentRootElementName = MovieListを定義することですが、MovieListに何百万もの映画を含めることができる場合、これは良い考えではないと思います!!
fragmentRootElementName の親タグを知る必要があるという同様の問題がありました。
そこで、元の StaxEventItemReader を拡張する CustomStaxEventItemReader を作成しました。
設定で設定できるプロパティparentElementを追加しました。そして、メソッド moveCursorToNextFragment() と doRead() をオーバーライドして、この問題に対処できるようにします。
今、私が持っているコードはあなたが必要としているものを正確に実行していませんが、私はそれを修正し、動作しているように見えます!!!
protected boolean moveCursorToNextFragment(XMLEventReader reader) {
try {
while (true) {
while (reader.peek() != null && !reader.peek().isStartElement()) {
reader.nextEvent();
}
if (reader.peek() == null) {
return false;
}
XMLEvent ev = reader.peek();
QName startElementName = ((StartElement) ev).getName();
// Take note of current parent element. Must be one of
// ParentTags
String tmp = startElementName.getLocalPart();
for (ParentTags aTag : ParentTags.values()) {
if (aTag.toString().equals(tmp)) {
currentParent = tmp;
Attribute attr = ((StartElement) ev)
.getAttributeByName(new QName("Language"));
if (null != attr) {
parentAttribute = attr.getValue();
}
break;
}
}
if (startElementName.getLocalPart().equals(
fragmentRootElementName)) {
if ((fragmentRootElementNameSpace == null && parentElement
.equals(currentParent))
|| startElementName.getNamespaceURI().equals(
fragmentRootElementNameSpace)) {
return true;
}
}
reader.nextEvent();
}
} catch (XMLStreamException e) {
throw new DataAccessResourceFailureException(
"Error while reading from event reader", e);
}
}
基本的に、元の StaxEventReader のコードを見ると、xml ファイルのすべての要素を通過していることがわかります。= という名前の要素を rootElement に取得するたびに、true を返し、doRead はそれを非整列化し、関連付けられたオブジェクトを返します。
ここで、特定の親要素を見つけるためのコードを追加するだけです。私の XML はもう少し複雑だったので、ParentTags という Enum を使用しましたが、構成で定義された新しい parentElement の名前しか比較できませんでした。
したがって、実際の要素がparentElementと等しい場合、それをcurrentParentに割り当てて、属性を取得しようとするだけです。null でない場合は、parentAttribute プロパティに割り当てます。
その後、doRead() メソッドで、parentAttribute プロパティにアクセスして、ドメイン オブジェクトに設定できます。
protected T doRead() throws Exception {
if (noInput) {
return null;
}
T item = null;
if (moveCursorToNextFragment(fragmentReader)) {
fragmentReader.markStartFragment();
@SuppressWarnings("unchecked")
T mappedFragment = (T) unmarshaller.unmarshal(StaxUtils
.createStaxSource(fragmentReader));
item = mappedFragment;
logger.info("Item read : " + item);
currentIndex = cIndex.getAndIncrement();
T p = (T) item;
if (p instanceof myDomainObj) {
myDomainObj pp = (myDomainObj) p;
logger.info(pp);
logger.info("attribute parent = " + parentAttribute);
pp.setLanguage(parentAttribute);
}
fragmentReader.markFragmentProcessed();
}
return item;
}
これが十分に明確であることを願っています!
幸運を祈ります