2013-06-04 10 views
5

Voglio fare parmarsaling parziale di grande XML.Partial-unmarshalling con JAXB

XML ha seguente struttura:

<Records> 
    <Contract> 
     ... 
    </Contract> 
    <Contract> 
     ... 
    </Contract> 
    ... 
    <Contract> 
     ... 
    </Contract> 
    <Contract> 
     ... 
    </Contract> 
</Records> 

E risultato classe generata con XJC:

- Records 
    |- Contract 

Se seguo these (campione da JAXB-ri), ottengo l'errore:

Exception in thread "main" javax.xml.bind.UnmarshalException: unexpected element (uri:"http://somedomain.com", local:"Contract"). Expected elements are <{http://somedomain.com}Records> 

Se uso:

<jaxb:globalBindings localScoping="toplevel"/> 

ottengo l'errore:

org.xml.sax.SAXParseException: A class/interface with the same name "com.my.package.Text" is already in use. Use a class customization to resolve this conflict. 

Ma ho bisogno di cambiare molte classi. E questa non è una soluzione.

risposta

7
/** 
* User: r.ibragimov 
* Date: 04.06.13 
*/ 
public class PartialJAXB1 { 

    public static void main(String[] args) throws JAXBException, XMLStreamException, FileNotFoundException { 

     final QName qName = new QName("http://www.domain.com","Contract"); 

     InputStream inputStream = new FileInputStream(new File("c:\\test.xml")); 

     // create xml event reader for input stream 
     XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance(); 
     XMLEventReader xmlEventReader = xmlInputFactory.createXMLEventReader(inputStream); 

     // initialize jaxb 
     JAXBContext context = JAXBContext.newInstance(Records.class); 
     Unmarshaller unmarshaller = context.createUnmarshaller(); 

     XMLEvent e = null; 

     // loop though the xml stream 
     while((e = xmlEventReader.peek()) != null) { 

      // check the event is a Document start element 
      if(e.isStartElement() && ((StartElement)e).getName().equals(qName)) { 

       // unmarshall the document 
       Records.Contract contract = unmarshaller.unmarshal(xmlEventReader, Records.Contract.class).getValue(); 
       System.out.println(contract); 
      } else { 
       xmlEventReader.next(); 
      } 

     } 

    } 
} 
+0

Grazie, funziona perfettamente! – Margaret

2

Classi Generazione Livello superiore

I want get just Records class and separate Contract class.

Per impostazione predefinita un'implementazione JAXB genererà classi corrispondenti ai tipi complessi anonimi come le classi interne statiche. Se si vuole che tutto sia una classe di livello superiore è possibile, come si affermato nella sua domanda di utilizzare il seguente personalizzazione legame esterno:

<jaxb:bindings 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" 
    version="2.1"> 
    <jaxb:globalBindings localScoping="toplevel"/> 
</jaxb:bindings> 

Risoluzione dei conflitti di nomi

I get error:

org.xml.sax.SAXParseException: A class/interface with the same name "com.my.package.Text 

Uno degli scopi delle classi interne statiche è prevenire conflitti di nome. Con tutte le classi di livello superiore è possibile utilizzare un file di bind esterno per rinominare la classe generata da un tipo complesso. Di seguito è riportato un esempio in cui la classe corrispondente al tipo complesso itemType verrà generata come Item.

<jaxb:bindings 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" 
    version="2.1"> 
    <jaxb:globalBindings localScoping="toplevel"/> 
    <jaxb:bindings schemaLocation="company.xsd"> 
     <jaxb:bindings node="//xsd:element[@name='employee']/xsd:complexType/xsd:sequence/xsd:element[@name='address']/xsd:complexType"> 
      <jaxb:class name="EmployeeAddress"/> 
     </jaxb:bindings> 
    </jaxb:bindings> 
</jaxb:bindings> 

Utilizzo del file Binding

Si specifica il file di collegamento nella chiamata XJC utilizzando il flag -b

xjc -b binding.xml your-schema.xsd 

Per ulteriori informazioni

+0

Si chiede già la mia altra domanda :) Questa domanda, su come fare classe separata. – IRus

+0

O, circa, come separare paramentariamente la struttura seguente. – IRus

+0

@IRus - La mia risposta attuale ti aiuterà con l'errore 'stesso nome' che stai vedendo. Non capisco la parziale parte non razziale della tua domanda. –