29

たとえば、別のスキーマをインポートする単純なスキーマがあります。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>

このスキーマからクラスを生成するためにMetroxjcAntタスクを使用しています。私が遭遇している問題は、私が対話しているサードパーティのアプリケーションが名前空間に特有のものであるということです。この場合、文字列値が必要なので、シリアル化する必要があります。これには定型コードを使用します。

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"に基づいて解析しているということです。ソフトウェアが機能するに、「サードパーティ」である必要があります。

結果の文字列で検索と置換を行う以外に、これを回避する方法を知っている人はいますか?おそらくカスタムバインディングルール?

4

4 に答える 4

28

http://hwellmann.blogspot.com/2011/03/jaxb-marshalling-with-custom-namespace.html

これは、その方法を示しています。

別: http://www.systemmobile.com/?p=280

リンクが切れた場合のキー ビット:

com.sun.xml.bind.marshaller パッケージにある NamespacePrefixMapper クラス。抽象クラスには、実装するメソッドが 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 も実装して、名前空間のカスタマイズを単一のクラスに集中させることができます。

于 2009-12-30T23:55:29.533 に答える
12

私はJava SE6でそれをテストましたが、Java SE 5のソリューションと比較して小さな変更が必要です(上記のように):

    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 番目のプロパティ.internal.には、Java SE5 バージョンと比較して、パッケージ名に追加が含まれています。私がまだ見つけていないのは、どの名前空間 URI がデフォルトの名前空間 ("") になるかを Marshaller に伝える方法です。メソッド getPreferredPrefix() をオーバーライドして空の文字列を返すと、マーシャラーはデフォルトの名前空間の属性を書き込む際に問題が発生します (この場合、ns1 という名前の新しい名前空間が作成されます)。

于 2011-01-11T13:25:47.557 に答える
0

これを行うには、 という内部 JAXB 実装クラスを使用する方法がありますNamespacePrefixMapper。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 実装クラスであるため、将来のバージョンで存在するという保証はありません。

于 2009-12-31T00:18:55.900 に答える