2010-11-24 5 views
1

を使用してJAXBを持つ任意の方法私はをサポートすることができますが、JAXBを使用して不明 XMLをインターリーブ? @XmlAnyElementを使用すると、仕事までしていないようです。..:@XmlAnyElement

私は他の名前空間からのインターリーブされた要素を可能にするためにXMLスキーマを記述し、ビルトインのJava 6のJAXB(でこれを使用しようとしています私はのAPIユーザーに JAXBライブラリを推奨してもらうという贅沢はないので、JAXB 2.2.1で完全に試してみませんでしたが、2.2.1でも動作しないと信じています)

ので、例えば、スキーマanything.xsd与えられ、このexample.xmlが有効である必要があります。

<?xml version="1.0" encoding="UTF-8"?> 
<container xmlns="http://example.com/schema" 
    xmlns:other="http://example.com/other"> 
    <rootFiles> 
     <other:before>before rootFile</other:before> 
     <rootFile path="test" /> 
     <other:after>after rootFile</other:after> 
    </rootFiles> 
</container> 

<rootFile>の前後に、他の名前空間からのXMLを許可する必要があります。


スキーマワイズこれはかなりまっすぐ進む<xsd:any>要素の前と<rootFile>ため<xsd:element>後に使用しています。 オプションの要素の周りにインターリーブされているのは、やりにくいですが、それは別の投稿です。トリックは、代わりにラップグループをオプションにすることです:プロパティ任意の-プロパティの前/後に別のプロパティ名を指定するには:<xsd:sequence minOccurs="0"><xsd:element minOccurs="1" .. /><xsd:any /></xsd:sequence>

私はJAXBを追加しました。 プロパティ "Any"は既に定義されています

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<container xmlns="http://example.com/schema"> 
    <rootFiles> 
     <other:before xmlns:other="http://example.com/other">before rootFile</other:before> 
     <other:after xmlns:other="http://example.com/other">after rootFile</other:after> 
     <rootFile path="test"/> 
    </rootFiles> 
</container> 

これは、それが不可能:

問題は、JAXBは再びアンマーシャリング要素(参照完全example Maven Project)のうち、マーシャリング時に見られるように、anyBefore財産へのすべての未知の要素をチャックように見えるということですrootFiles.getAnyAfter()を調べて、どこの未知のものがどこに来たかを調べることができました。しかし、私にとっては真剣に、インタリーブされたXMLを邪魔することなくXMLをもう一度シリアル化することは不可能です。

XJCが正しく2 任意の -propertiesを作成しない:

@XmlAccessorType(XmlAccessType.FIELD) 
    @XmlType(name = "", propOrder = { 
     "anyBefore", 
     "rootFile", 
     "anyAfter" 
    }) 
    public static class RootFiles { 

     @XmlAnyElement(lax = true) 
     protected List<Object> anyBefore; 
     @XmlElement(required = true) 
     protected List<Container.RootFiles.RootFile> rootFile; 
     @XmlAnyElement(lax = true) 
     protected List<Object> anyAfter; 

XmlAnyElementのJavaDocは言う:

このアノテーションは、のXmlElement、XmlAttribute、XmlValue、XmlElements、XmlIDと相互に排他的ですおよびXmlIDREF。 クラスおよびそのスーパークラスには、XmlAnyElementアノテーション付きJavaBeanプロパティは1つしか存在できません。このことから

私はJAXBが本当に二@XmlAnyElement気にしないと結論し、ちょうど最初どのプロパティにすべての直接の未知数を配置しました。私は何をすべきかについて固執しています。

私の主な関心事は、正しい場所にある未知の要素を保存することです(注文は保存されているようです)。特に構文解析には気をつけません。 要素のいくつかの変更の後に再びXMLを返します。


ここで、ランダムなXMLを許可するような愚かなスキーマを設計する理由が不思議に思うかもしれません。残念ながら私のせいではありません。私は単にをAdobe UCF specificationsからXML schemaに手動で変換しようとしています。私はJAXBで使用できます。問題は、どの外国XML要素を可能にし、META-INF/container.xmlの属性this wordingです:

UCFユーザ​​ーエージェントはcontainer.xmlファイルに認識されていない要素(とその内容)と認識されていない属性を無視しなければなりません準拠します、認識できない要素や他の名前空間の認識されない属性などが含まれます。

適合するcontainer.xmlファイルは、RELAX NG UCFスキーマに従って、すべての要素(およびこれらの要素の子ノード)と他の名前空間の属性を削除した後、その要素をルート要素として有効にする必要があります。

私はそれらを無視することができると言うだけの要素を削除することができますが、将来的には何かを意味する拡張機能があれば、少なくとも私はそのような要素を正しく保存することができます。私はJAXBを使ってこのことが難しいと思っています。

Marshaller/Unmarshallerにいくつかの魔法のように私がこれを達成する方法について提案はありますか?

答えて

4

@XmlAnyElement@XmlElementRefまたは@XmlElementRefsを組み合わせることができます。 <xs:choice maxOccurs="unbounded" .../>を試し、XMLスキーマで

@XmlElementRef(name="rootFile") 
@XmlAnyElement 
protected List<Object> beforeOrRootFileOrAfter; 

:あなたの注釈は次のようになります。

+0

ありがとう、それは十分にうまくいくかもしれません。 'RootFile'オブジェクトを見つけるためにオブジェクトを繰り返し処理する必要がありますが、既知のオブジェクトの前後にある他のオブジェクトを公開するという追加の利点があります。 –

+0

ああ、少なくとも1つのRootFileは必要ありません(minOccurs = 1を指定すると、1つの他のものから離れていくことができます)が、コード内で確認できます。 –

関連する問題