.XSD dosyalarından Java sınıfları oluştur…?


127

QuickBooks'tan gönderebileceğim / alabileceğim XML isteklerini / yanıtlarını tanımlayan devasa bir QuickBooks SDK .XSD şema dosyam var.

Bu .XSD dosyalarından kolayca Java sınıfları oluşturabilmek istiyorum, bunları daha sonra XML'i Java nesnelerine ve Java nesnelerini XML'e sıralamak için kullanabileceğim.

Bunu yapmanın kolay bir yolu var mı?

İdeal olarak, çalışma zamanında temel Java dağıtımının dışında herhangi bir kitaplık gerektirmez. Ama esnekim ...


6
El ile oluşturma istiyorsanız, .xsd dosyasını tutulma projenize yerleştirin, dosyayı sağ tıklayın ve ardından "
oluştur

Yanıtlar:


121

JAXB TAM OLARAK istediğinizi yapar. 1.6'dan başlayarak JRE / JDK'da yerleşiktir


7
Ne yazık ki, bu işlevsellik artık Java 9'dan itibaren kullanılamayacak. Bunun nedeni, ilgili sınıfların (özellikle com.sun.tools.xjc. * Sınıflarının) artık JDK aracılığıyla kullanılamayacak olmasıdır.
Marco

4
Bunun JDK'dan kaldırılmasının bir sorun olacağını düşünmüyorum, çünkü java.net projesi (yanıtta bağlantılı) muhtemelen kalacaktır.
stmoebius

1
Burada açıklandığı gibi , bağımlılıkları bir komut satırı argümanıyla Java 9'da ekleyebilir veya bağımlılığı manuel olarak ekleyebilirsiniz.
Matthias Ronge

118

Yukarıdaki "JAXB kullan" açıklamalarını genişletmek için,

Windows'ta "%java_home%\bin\xjc" -p [your namespace] [xsd_file].xsd

Örneğin, "%java_home%\bin\xjc" -p com.mycompany.quickbooks.obj quickbooks.xsd

Biraz bekleyin ve iyi biçimlendirilmiş bir XSD dosyanız varsa, bazı iyi biçimlendirilmiş Java sınıfları alacaksınız.


3
Çok teşekkürler! Kapsüllenmiş yerine en üst düzey sınıfları oluşturmak için bkz: stackoverflow.com/questions/13175224/… . Ve eğer sınıf adı çatışmalarına yol açıyorsa, bakınız: stackoverflow.com/questions/13414407/…
yarın

38

Java'yı XML'e ve XML'yi Java'ya 5 dakikadan daha kısa sürede kodlamaya başlamak istiyorsanız, Basit XML Serileştirmeyi deneyin. JAXB API'sini öğrenmek için saatler harcamayın http://simple.sourceforge.net/download/stream/doc/tutorial/tutorial.php

Bununla birlikte, JAXB öğrenmeye gerçekten meraklıysanız, işte mükemmel bir eğitim http://blogs.oracle.com/teera/entry/jaxb_for_simple_java_xml

Öğreticinin içeriği:

Basit Java-XML serileştirme için JAXB

Java'da XML serileştirme yapmanın birkaç yolu vardır. Ayrıştırma ve serileştirme üzerinde ayrıntılı denetim istiyorsanız, daha iyi performans için SAX, DOM veya Stax'ı tercih edebilirsiniz. Yine de, sık sık yapmak istediğim şey, POJO'lar ve XML arasında basit bir eşleştirme. Ancak, manuel olarak XML olay ayrıştırması yapmak için Java sınıfları oluşturmak önemsiz değildir. Yakın zamanda JAXB'yi hızlı ve kullanışlı bir Java-XML eşlemesi veya serileştirme olarak buldum.

JAXB birçok kullanışlı özellik içerir, burada referans uygulamasına göz atabilirsiniz. Kohsuke'nin Blogu da JAXB hakkında daha fazla bilgi edinmek için iyi bir kaynaktır. Bu blog yazısı için, size JAXB ile basit bir Java-XML serileştirmenin nasıl yapılacağını göstereceğim.

POJO'dan XML'e

Diyelim ki bir Öğe Java nesnem var. Bir Öğe nesnesini XML biçiminde serileştirmek istiyorum. İlk yapmam gereken şey, bu POJO'ya javax.xml.bind.annotation. * Paketinden birkaç XML ek açıklaması eklemektir. Item.java için kod listesi 1'e bakın

Koddan

  • @XmlRootElement(name="Item") kök öğe olmak istediğimi belirtir.
  • @XmlType(propOrder = {"name", "price"}) öğenin XML çıktısında düzenlenmesini istediğim sırayı gösterir.
  • @XmlAttribute(name="id", ...) id'nin kök öğenin bir özniteliği olduğunu belirtir.
  • @XmlElement(....) Fiyat ve adın Öğe içinde yer almasını istediğimi belirtir.

Benim Item.javahazırım. Sonra devam edebilir ve Item'ı sıralamak için JAXB komut dosyası oluşturabilirim.

//creating Item data object
Item item = new Item();
item.setId(2);
item.setName("Foo");
item.setPrice(200);
.....

JAXBContext context = JAXBContext.newInstance(item.getClass());
Marshaller marshaller = context.createMarshaller();
//I want to save the output file to item.xml
marshaller.marshal(item, new FileWriter("item.xml"));

Kod Listesinin tamamı için lütfen Kod Listeleme 2'ye bakın main.java. Çıktı Kodu Listesi 3 item.xmldosyası oluşturulur. Şöyle görünüyor:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns1:item ns1:id="2" xmlns:ns1="http://blogs.sun.com/teera/ns/item">

 <ns1:itemName>Foo</ns1:itemName>
<ns1:price>200</ns1:price>

</ns1:item>

Kolay değil mi? Alternatif olarak, marshal (...) yönteminin parametresini aşağıdaki gibi değiştirerek çıktı XML'sini metin Dizesi, Akış, Yazar, ContentHandler vb. Olarak yönlendirebilirsiniz.

...
JAXBContext context = JAXBContext.newInstance(item.getClass());
Marshaller marshaller = context.createMarshaller();
// save xml output to the OutputStream instance
marshaller.marshal(item, <java.io.OutputStream instance>);

...
JAXBContext context = JAXBContext.newInstance(item.getClass());
Marshaller marshaller = context.createMarshaller();
StringWriter sw = new StringWriter();
//save to StringWriter, you can then call sw.toString() to get java.lang.String
marshaller.marshal(item, sw);

XML'den POJO'ya

Süreci tersine çevirelim. Şimdi bir parça XML dizgi verisine sahip olduğumu ve bunu Item.java nesnesine dönüştürmek istediğimi varsayalım. XML verileri (Kod listesi 3) şuna benzer:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns1:item ns1:id="2" xmlns:ns1="http://blogs.sun.com/teera/ns/item">
<ns1:itemName>Bar</ns1:itemName>
<ns1:price>80</ns1:price>
</ns1:item>

Daha sonra bu xml kodunu Item nesnesine göre

...
ByteArrayInputStream xmlContentBytes = new ByteArrayInputStream (xmlContent.getBytes());
JAXBContext context = JAXBContext.newInstance(Item.getClass());
Unmarshaller unmarshaller = context.createUnmarshaller();
//note: setting schema to null will turn validator off
unmarshaller.setSchema(null);
Object xmlObject = Item.getClass().cast(unmarshaller.unmarshal(xmlContentBytes));
return xmlObject;
...

Kod Listesinin tamamı için lütfen Kod Listesi 2'ye (main.java) bakın. XML kaynağı hem Akıştan hem de dosyadan birçok biçimde gelebilir. Tek fark yine yöntem parametresidir:

...
unmarshaller.unmarshal(new File("Item.xml")); // reading from file
...
// inputStream is an instance of java.io.InputStream, reading from stream
unmarshaller.unmarshal(inputStream);

XML Şeması ile Doğrulama

Burada bahsetmek istediğim son şey, Java nesnesinin eşlemesini kaldırmadan önce giriş XML'sini şema ile doğrulamaktır. İtem.xsd adında bir XML şema dosyası oluşturuyorum. Kod Listelemenin tamamı için lütfen Kod Listeleme 4'e (Öğe.xsd) bakın. Şimdi yapmam gereken, bu şemayı doğrulama için kaydettirmek.

...
Schema schema = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI)
.newSchema(new File("Item.xsd"));
unmarshaller.setSchema(schema); //register item.xsd shcema for validation
...

XML verilerini POJO'ya göndermeye çalıştığımda, giriş XML'si şemaya uygun değilse, istisna yakalanacak. Kod Listesinin tamamı için lütfen Kod Listeleme 5'e (geçersiz_item.xml) bakın.

javax.xml.bind.UnmarshalException
- with linked exception:
javax.xml.bind.JAXBException caught: null
[org.xml.sax.SAXParseException: cvc-datatype-valid.1.2.1: 'item1' is
                                not a valid value for 'integer'.]

Burada 'id' özniteliğini tamsayı yerine dizge olarak değiştiriyorum.

XML girişi şemaya göre geçerliyse, XML verileri Item.java nesnesine başarılı bir şekilde sıralanacaktır.


1
Bu çok umut verici görünüyor ve ihtiyaç duyduğum şey için onunla çalışmak JAXB gibi büyük ve karmaşık bir şeyden çok daha basit ve daha hoş görünüyor . Ne yazık ki, mevcut .XSD'mi .class dosyalarına dönüştürmenin herhangi bir yolunu göremiyorum, gerçekten başlamam gereken şey bu. Bunu yapmanın bir yolu var mı?
Keith Palmer Jr.

7
Maalesef JAXB Eğitimi'nin bulunduğu blog çevrimdışı.
Luis C'de

jaxb2-maven-eklentisini kullanarak bunu kolayca yapabiliriz, bu eğiticiyi kontrol edin journaldev.com/1312/…
Pankaj

""% java_home% \ bin \ xjc "-p [ad alanınız] [xsd_file] .xsd" ile ilgili karmaşık olan nedir?
gorefest

30

Eclipse IDE'yi kullanma: -

  1. xsd'yi yeni / mevcut bir projeye kopyalayın.
  2. Sınıf yolunuzda JAXB için gerekli JAR'ların olduğundan emin olun. Buradan bir tane indirebilirsiniz .
  3. XSD dosyasına sağ tıklayın -> Oluştur -> JAXB sınıfları.

17

en kolay yol komut satırı kullanmaktır. .Xsd dosyanızın dizinini yazmanız yeterlidir:

xjc myFile.xsd.

Böylece, java tüm Pojo'ları oluşturacaktır.


14

Maven bu amaçla kullanılabilir, bazı bağımlılıklar eklemeniz ve sadece uygulamanızı temizlemeniz gerekir. Hedef klasörünüzde otomatik olarak oluşturulan tüm sınıfları alacaksınız.

Onları hedeften istenen yere kopyalamanız yeterlidir, işte xsd dosyalarından sınıflandırılmış oluşturmak için kullandığım pom.xml:

    <plugin>
     <groupId>org.codehaus.mojo</groupId>
     <artifactId>jaxb2-maven-plugin</artifactId>

     <executions>
      <execution>
       <goals>
        <goal>xjc</goal>
       </goals>
      </execution>
     </executions>
     <configuration>
      <schemaDirectory>src/main/webapp/schemas/</schemaDirectory>
     </configuration>
    </plugin>

   </plugins>
  </pluginManagement>
 </build>
</project>

Xsd dosyalarınızı "src / main / webapp / schemas /" altına yerleştirin ve maven bunları derleme zamanında bulacaktır.

Bunun size yardımcı olacağını umuyoruz, daha fazla bilgi http://www.beingjavaguys.com/2013/04/create-spring-web-services-using-maven.html adresinde bulunabilir.

Umarım yardımcı olur :)


1
Bu gerçekten kaynaklar dizini ile çalışıyor mu? (src / main / resources / No XSD files found. Please check your plugin configuration.
schemas


7

En iyi seçenek %java_home%\bin\xjc -p [your namespace] [xsd_file].xsd.

Ayrıca burada tersine mühendislik yapma seçeneğimiz olup olmadığı konusunda bir sorum var. evet ise pojo sınıfından xsd üretebilir miyiz?


XJC sadece java6 mevcuttur
Sree

7

Harici bir kitaplık kullanmaktan rahatsız olmazsanız , bunu geçmişte yapmak için Castor'u kullandım .


Castor ile kod üretirseniz, üretilen sınıflar olaydan sonra hala Caster'a bağımlı mı? Ya da bu sınıfları Castor kitaplıkları olmayan bir makineye taşıyabilir miyim ve hala çalışırlar mı?
Keith Palmer Jr.

Hayır, üretilen sınıflar Castor kitaplıklarına bağlı değildir.
dave

Bunu yapmak için Castor'un nasıl kullanılacağına dair iyi eğitimler var mı? Çok umut verici görünüyor ... ama Java, en azından söylemek gerekirse, en güçlü dilim değil. Hangi Castor dosyalarını / paketlerini indirmem gerektiğinden ve kod üretimini nasıl yapacağımdan emin değilim ... Etrafta adım adım acemi örnekleri var mı?
Keith Palmer Jr.

Castor SourceGenerator sınıfının nasıl kullanılacağına ilişkin belgeler için bu sayfaya göz atın: castor.org/sourcegen.html
Marc Novakowski

2
Görünüşe göre teker çoktan ölmüş ... Dokümanlar bağlantılarının hepsi 404.
Pawel Veselov

5

JAXB Sınırlaması.

JAXB üzerinde çalıştım, kanımca XML ve Java nesneleri arasındaki verilerle başa çıkmanın güzel bir yolu. Olumlu taraflar, kanıtlanmış ve daha iyi performans ve çalışma süresi boyunca veriler üzerinde kontrol sağlar. Yerleşik araçların veya komut dosyalarının iyi bir şekilde kullanılması, birçok kodlama çabasını ortadan kaldıracaktır.

Yapılandırma kısmının hemen bir iş olmadığını anladım ve geliştirme ortamı kurulumunu almak için saatler harcadım.

Ancak karşılaştığım aptalca bir sınırlama nedeniyle bu çözümü bıraktım. XML Şema Tanımım (XSD), "değer" adında bir özniteliğe / öğeye sahip ve XSD'yi olduğu gibi kullanmam gerekiyor. Bu çok az kısıtlama benim bağlama adımımı zorladı ve XJC "Özellik 'Değeri' zaten kullanılmış."

Bu, JAXB uygulamasından kaynaklanmaktadır, bağlama işlemi, her sınıfa birkaç özellik ekleyerek ve bunlardan biri bir değer niteliği olarak, XSD'den Java nesneleri oluşturmaya çalışır. XSD'mi işlediğinde, bu isimde zaten bir özellik olduğundan şikayet etti.


4

JAXB'nin XJC'si buna olası bir cevap değil mi? Ben de aynı şeyi başarmaya çalışıyorum. Yine de "deneme" aşamasında. XJC'de geldi, bu yüzden paylaşmayı düşündüm.



Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.