2010-10-29 19 views
7

XJC sembra ignorare completamente mixed="true" sugli elementi XML Schema, pertanto non mi consente di estrarre il contenuto del testo. Dal seguente XML di esempio, devo essere in grado di estrarre "Titolo Testo". Senza mixed="true" essere riconosciuto, non di accesso si crea né si deserializzati da XML:Compilatore JAXB XJC che ignora mixed = true sui documenti XML Schema

<?xml version="1.0" encoding="UTF-8"?> 
<title xmlns="urn:hl7-org:v3" integrityCheck="true">Title Text</title> 

Ecco uno schema completo, ma ridotto al minimo che illustra il problema:

<?xml version="1.0" encoding="UTF-8" standalone="no"?> 
<xs:schema targetNamespace="urn:hl7-org:v3" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns="urn:hl7-org:v3" 
    xmlns:mif="urn:hl7-org:v3/mif" 
    elementFormDefault="qualified"> 

    <xs:complexType name="ST" mixed="true"> 
    <xs:complexContent> 
     <xs:restriction base="ED"> 
      <xs:sequence> 
       <xs:element name="reference" type="xs:string" minOccurs="0" maxOccurs="0"/> 
       <xs:element name="thumbnail" type="xs:string" minOccurs="0" maxOccurs="0"/> 
      </xs:sequence> 
      <xs:attribute name="compression" type="xs:string" use="prohibited"/> 
     </xs:restriction> 
     </xs:complexContent> 
    </xs:complexType> 

    <xs:complexType name="ED" mixed="true"> 
    <xs:complexContent> 
     <xs:extension base="BIN"> 
     <xs:sequence> 
      <xs:element name="reference" type="xs:string" minOccurs="0" maxOccurs="1" /> 
      <xs:element name="thumbnail" minOccurs="0" maxOccurs="1" type="xs:string" /> 
      </xs:sequence> 
     <xs:attribute name="compression" type="xs:string" use="optional" /> 
     <xs:attribute name="integrityCheck" type="xs:string" use="optional" /> 
     <xs:attribute name="integrityCheckAlgorithm" type="xs:string" use="optional" default="SHA-1" /> 
     </xs:extension> 
    </xs:complexContent> 
    </xs:complexType> 

    <xs:complexType name="BIN" abstract="true" mixed="true"> 
    <xs:complexContent> 
     <xs:extension base="ANY"> 
     <xs:attribute name="representation" use="optional" type="xs:string" default="TXT" /> 
     </xs:extension> 
    </xs:complexContent> 
    </xs:complexType> 

    <xs:complexType name="ANY" abstract="true"> 
    <xs:attribute name="nullFlavor" type="xs:string" use="optional" /> 
    </xs:complexType> 

    <xs:element name="title" type="ST" /> 
</xs:schema> 

Si noti che nella sopra ho mescolato = "vero". Nonostante ciò, il frammento di schema generato non contiene un riferimento ad esso, né la classe generata utilizzare il XmlMixed annotazioni, né un valore o il contenuto di accesso:

/** 
* <p>Java class for ST complex type. 
* 
* <p>The following schema fragment specifies the expected content contained within this class.                                    
* 
* <pre> 
* <complexType name="ST"> 
* <complexContent> 
*  <restriction base="{urn:hl7-org:v3}ED"> 
*  <sequence> 
*   <element name="reference" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="0" minOccurs="0"/> 
*   <element name="thumbnail" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="0" minOccurs="0"/> 
*  </sequence> 
*  </restriction> 
* </complexContent> 
* </complexType> 
* </pre> 
* 
*/ 
@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(name = "ST") 
public class ST 
    extends ED 
{ 
} 

Perché XJC/JAXB trascurando completamente il mio contenuto misto campi? Ho provato sia JAXB 2.1 che JAXB 2.2 ma nel codice generato sono presenti solo differenze banali.

Nota: Non riesco a modificare lo schema poiché lo schema corrente è uno schema di assistenza sanitaria conforme agli standard (HL7).

+0

Che aspetto ha la classe BIN? –

+0

@ Blaise - Ora ho incluso uno schema piccolo ma completo che dimostra il problema. –

+0

Hai mai trovato una soluzione a questo problema? Sto affrontando lo stesso. Ho dovuto modificare la classe generata (BIN). – AHungerArtist

risposta

5

Dopo ulteriori ricerche non ho potuto fare altro che concludere che si trattava di un bug che ho archiviato. È stato riconosciuto come JAXB issue #792.

+0

"È un bug" sembra una risposta valida. Perché i downvotes? –

4

http://blogs.oracle.com/mgrebac/entry/handling_extended_mixed_content_in

questo ha funzionato! Basta creare un file di collegamento in questo modo:

<?xml version="1.0" encoding="UTF-8"?> 
<jaxb:bindings 
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" jaxb:version="2.0" 
xmlns:xjc= "http://java.sun.com/xml/ns/jaxb/xjc" jaxb:extensionBindingPrefixes="xjc"> 
    <jaxb:globalBindings generateMixedExtensions="true"/> 
</jaxb:bindings> 

quindi utilizzare il parametro -b nella riga di comando con il modo in cui di solito si fa.

+0

Ricordo di aver visto quel post in quel momento e, IIRC, il mio problema era leggermente diverso, anche se correlato. Ma ... non riesco più a ricordare con molta certezza. –

+0

Crea un campo di contenuto, sfortunatamente è un brutto elenco , ma è meglio che non averlo, soprattutto visto che anch'io sto usando gli schemi HL7. Questa era la stessa classe con cui stavo avendo problemi, in effetti. – AHungerArtist

2

Gli anni passano, ma questo schema continua a turbare la gente! Ho lottato con lo stesso XSD (HL7) negli ultimi giorni, specialmente per la gestione dei tipi di elementi di contenuto misto.

Il mio requisito iniziale era l'opposto del poster originale, poiché avevo bisogno di scrivere un testo semplice all'interno di un elemento misto. Ma devo essere in grado di leggere anche questo tipo di contenuti, quindi ho applicato la stessa soluzione suggerita in un'altra risposta, ovvero la creazione di un file di bind personalizzato e il suo utilizzo nella procedura guidata "Classi JAXB dallo schema" di Eclipse. In tal caso, è possibile scegliere in modo specifico quali file di associazione utilizzare in una delle finestre di dialogo della procedura guidata.

Di conseguenza, le classi vengono generate con un contenuto List<Serializable> ogni volta che viene trovato un tipo di elemento misto. Diventa un po 'complicato estrarre la singola informazione che è effettivamente necessaria, ma almeno sei sicuro di poter accedere in modo programmatico a tutto ciò che è presente in un file XML che aderisce a XSD.

Si può anche navigare in contenuti misti più complessi quali:

<v3:name> 
    <v3:given>Sample Given Name</v3:given> 
    <v3:family>Sample Family Name</v3:family> 
</v3:name> 

Dove name è definito come tale (ho rimosso contenuti non utile per questo esempio dall'originale XSD):

<xs:complexType name="EN" mixed="true"> 
    <xs:complexContent> 
     <xs:sequence> 
      <xs:choice minOccurs="0" maxOccurs="unbounded"> 
       <xs:element name="delimiter" type="en.delimiter"/> 
       <xs:element name="family" type="en.family"/> 
       <xs:element name="given" type="en.given"/> 
       <xs:element name="prefix" type="en.prefix"/> 
       <xs:element name="suffix" type="en.suffix"/> 
      </xs:choice> 
     </xs:sequence> 
    </xs:complexContent> 
</xs:complexType> 

Tipi en.family, en.given e tali sono mescolati (e per il nostro scopo non abbiamo bisogno di sapere altro).

Così, quando si accede a contenuti di nome, il suo List<Serializable> sarà composto da:

  1. un String, essendo gli spazi vuoti tra <v3:name> e <v3:given>
  2. un EnGiven elemento
  3. un String, essendo gli spazi vuoti tra </v3:given> e <v3:family>
  4. un EnFamily elemento
  5. un String, essendo gli spazi vuoti tra </v3:family> e </v3:name>

EnGiven e contenuti EnFamily s' saranno ciascuna composta di un unico String, rispettivamente, 'Sample Data Nome' e 'Sample Nome Famiglia'. Di nuovo, è un po 'complicato, e probabilmente hai dovuto mettere un po' di logica per gestire i casi specifici, ma puoi gestirlo in questo modo.

A proposito, il popolamento di un elemento è banale: basta aggiungere una stringa al contenuto desiderato di List<Serializable>.