たとえば、別のスキーマをインポートする単純なスキーマがあります。 2番目のスキーマ(urn:just:attributes、just-attributes.xsd)は、属性グループを定義するだけです。
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.example.org/MySchema"
xmlns:tns="http://www.example.org/MySchema"
elementFormDefault="qualified"
xmlns:ja="urn:just:attributes">
<import schemaLocation="just-attributes.xsd" namespace="urn:just:attributes"/>
<element name="MyElement">
<complexType>
<attributeGroup ref="ja:AttributeGroup"/>
</complexType>
</element>
</schema>
私はこのスキーマからクラスを生成するためにMetro xjc Antタスクを使用しています。私が遭遇している問題は、私が対話しているサードパーティのアプリケーションが名前空間に特有であるということです。この場合、文字列値が必要なので、シリアル化する必要があります。これには定型コードを使用します。
private static <T> String marshal(T object) throws JAXBException{
OutputStream outputStream = new ByteArrayOutputStream();
JAXBContext jaxbContext = JAXBContext.newInstance(object.getClass());
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.marshal(object, outputStream);
return outputStream.toString();
}
それは私に何かに沿って何かを与えます
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:MyElement xmlns:ns1="urn:just:attributes" xmlns:ns2="http://www.example.org/MySchema" ns1:attrib1="1234" ns1:attrib2="5678"/>
私が抱えている問題は、このサードパーティがxmlns:thirdpartyns="urn:just:attributes"
、つまり、名前空間に指定されたnameに基づいて解析されます。 has彼らのソフトウェアが機能するための「サードパーティ」であること。
結果の文字列で検索と置換を行う以外に、これを回避する方法を誰かが知っていますか?おそらくカスタムバインディングルールですか?
http://hwellmann.blogspot.com/2011/03/jaxb-marshalling-with-custom-namespace.html
これはその方法を示しています。
別: http://www.systemmobile.com/?p=28
リンクが停止した場合のキービット:
namespacePrefixMapperクラス。com.Sun.xml.bind.marshallerパッケージにあります。抽象クラスには、実装するメソッドが1つあります。
public abstract String getPreferredPrefix(
String namespaceUri,
String suggestion,
boolean requirePrefix);
その後
Marshaller marshaller =
jaxbContext.createMarshaller();
marshaller.setProperty(”com.Sun.xml.bind.namespacePrefixMapper”,
new MyNamespacePrefixMapper());
Javax.xml.xpath.XPathも使用している場合、NamespacePrefixMapperはjavax.xml.namespace.NamespaceContextを実装して、単一のクラスで名前空間のカスタマイズを集中化することもできます。
私は that をJava SE6でテストしましたが、Java SE 5(説明どおり above ):
Marshaller m = context.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE );
m.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
m.setProperty("com.Sun.xml.internal.bind.namespacePrefixMapper", mapper);
したがって、上記の3番目のプロパティには、Java SE5バージョンと比較して、パッケージ名に追加の.internal.
が含まれています。私がまだ見つけていないのは、どの名前空間URIがデフォルトの名前空間( "")になるかをマーシャラーに伝える方法です。 getPreferredPrefix()メソッドをオーバーライドして空の文字列を返すと、Marshallerはデフォルトのネームスペースの属性の書き込みに問題があります(この場合、ns1という新しいネームスペースが作成されます)。
同じ質問がありました。 package-info.Java
(ない場合は、手動で作成できます)xmlns
の部分を追加します。
@javax.xml.bind.annotation.XmlSchema(xmlns = {
@javax.xml.bind.annotation.XmlNs(namespaceURI = "urn:just:attributes", prefix = "thirdpartyns") },
elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
これを行う方法があり、これはNamespacePrefixMapper
と呼ばれる内部JAXB実装クラスを使用します。 JAXB RIでは、これはcom.Sun.xml.bind.marshaller
ですが、Java6ではcom.Sun.xml.internal.bind.marshaller
。
これは抽象クラスです。名前空間URIをプレフィックスにマッピングする抽象メソッドをサブクラス化して実装できます。
次に、そのサブクラスのインスタンスをマーシャラーに注入します。
JAXBContext context = ...
Marshaller marshaller = context.createMarshaller();
NamespacePrefixMapper prefixMapper = new MyPrefixMapperImpl();
marshaller.setProperty("com.Sun.xml.bind.namespacePrefixMapper", prefixMapper);
プロパティ名はJava6バージョンでは異なるものになりますが、あなたはそのアイデアを理解しました。
これは内部JAXB実装クラスであるため、将来のバージョンで存在する保証はありません。