2016-01-25 29 views
12

Aşağıdaki kodu düşünün. Bu nedenle ilk önce, sonra buserialize JAXB'ın POJOs

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<customer xmlns="http://www.another.org/package"> 
    <id>123</id> 
</customer> 

gibi bakmak veya kaldıracaktır aynı pojo farklı bir asıl bir ikinci bir xml oluşturmak gelmez cari kodu gibi çıktı

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<customer xmlns="http://www.example.org/package"> 
    <id>123</id> 
</customer> 

yazdırmak isteyen hep birlikte ad alanı

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<customer> 
    <id>123</id> 
</customer> 
+0

Sen * @ XmlSchema * bölümü için ekstra bir kod parçacığını yapmalıdır: Bir Person olarak Customer nesneyi sıralamakta gerekirse Örneğin, başka bir OXM dosyası ekleyerek bu yapabileceğini ama kolayca gözden kaçabilir. – jah

cevap

7

Bu güzel bir soru. Bunun yerine JAXB'ın düğüm düzeyinde işe yarayabilir tip-seviyesinde çalışan

. Hemen hemen hiçbir yük bulunmamaktadır.

önemli bir göre QName tanımı ile temsil ettiği, XML-düğüm iş mantığı sınıfları arasından JAXBElement (düğüm seviyesi elemanları) erişmek ve özelleştirmek/yaratıyor.

QName hiç ad alanına tam olarak nitelenmiş ad arasında değişen özelleştirme için birçok seçenek sunar. Tek uyarı, öneksiz bir isim alanının kullanılması mümkün değildir. Jaxb, siz sağlamazsanız varsayılan bir ad alanı kullanacaktır.

Örnek:

QName elaborateQName = new QName("http://www.another.org/package", "customer", "myNs"); 
QName simpleQName = new QName("customer"); 

JAXBElement jx1 = new JAXBElement(elaborateQName, customer.getClass(), customer); 
JAXBElement jx2 = new JAXBElement(simpleQName, customer.getClass(), customer); 

m.marshal(jx1, System.out); 
m.marshal(jx2, System.out); 

Bu aşağıdaki çıktıyı üretecek:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<myNs:customer xmlns:myNs="http://www.another.org/package"> 
    <id>123</id> 
</myNs:customer> 

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<customer> 
    <id>123</id> 
</customer> 

öneki olmadan bir ad kullanarak mümkün değildir. Boş öneki veya varsayılan önek ile sonuçlanacaktır parametre olarak eşdeğer XMLConstants.DEFAULT_NS_PREFIX bir QName çalışırken (gibi NS1) üretilen:

// QName defaultNs = new QName("http://www.another.org/package", "customer", ""); 

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<ns2:customer xmlns:ns1="http://www.another.org/package"> 
    <id>123</id> 
</ns2:customer> 

prefix için parametre olarak null adlı kullanarak bir özel durum elde edilir:

java.lang.IllegalArgumentException: prefix cannot be "null" when creating a QName 
at javax.xml.namespace.QName.<init>(QName.java:251) 
+0

package-info.java örneği içinde, jaxb araçları tarafından otomatik olarak üretiliyor – danidacar

+1

JAXB oluşturma işleminizde etkisi varsa, package-info.java jenerasyonunu hiç atlamayı deneyebilirsiniz (xjc's -npa seçeneği ile) – jah

3

xmlns Moxy ile öznitelik kök nasıl geçersiz kılınır:

EclipseLink MOXy, kök öğenizin varsayılan ad alanını değiştirmek de dahil olmak üzere, JAXB sıralamasının kolayca özelleştirilmesini sağlar. Varsayılan ad geçersiz XML eşleme (OXM) için Nesne geçerli:

<?xml version="1.0"?> 
<xml-bindings xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm" version="2.5"> 
    <xml-schema element-form-default="QUALIFIED" namespace="http://www.another.org/package"/> 
</xml-bindings> 

, varsayılan ad olduğundan bunun yerine <xml-schema element-form-default="UNSET"/> kullanın.

Moxy Kurulumu:

1) projenize kütüphane ekleyin:

<dependency> 
    <groupId>org.eclipse.persistence</groupId> 
    <artifactId>org.eclipse.persistence.moxy</artifactId> 
    <version>2.6.2</version> 
</dependency> 

2) MOXY'nin fabrika (örnsrc/main/resources/com/sample/entity/jaxb.properties) etkinleştirmek için nesne modeli pakete bir jaxb.properties ekleyin:

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory 

3) Con your Instantiate metni OXM yapılandırmasına göre (bu örnekte OXM dosyasrc/main/resources/com/sample/entity/my-oxm.xml vardır):

Map<String, Source> metadata = Collections.singletonMap("com.sample.entity", new StreamSource(Customer.class.getResourceAsStream("my-oxm.xml"))); 
Map<String, Object> properties = Collections.singletonMap(JAXBContextProperties.OXM_METADATA_SOURCE, metadata); 
JAXBContext jaxbContext = JAXBContext.newInstance(new Class[] {customer.getClass()}, properties); 

Ardından da normal olarak JAXBContext üzerinde sıralanırken kullanabilirsiniz. Kullanmak istediğiniz her farklı OXM dosyası için ayrı bağlamları örnekleyin. Moxy ile

Ek özelleştirmeleri: Moxy hayır daha fazla etkili nesne modeli değiştirmenin manevra mantık var olsa bile open/closed principle uymak yapmadan gelecekte varlığın sıralanırken özelleştirmesine olanak tanır kullanma

Açık Marshaller sınıfları. Çok alakalı olarak

<?xml version="1.0"?> 
<xml-bindings xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm" version="2.5"> 
    <xml-schema element-form-default="QUALIFIED" namespace="http://www.example.com/person"/> 
    <java-types> 
     <java-type name="com.sample.entity.Customer"> 
      <xml-root-element name="person"/> 
      <java-attributes> 
       <xml-attribute java-attribute="id" name="personId"/> 
       <xml-element java-attribute="id" xml-path="someOtherId/text()"/> 
      </java-attributes> 
     </java-type> 
    </java-types> 
</xml-bindings>