2011-11-30 13 views
13

Estoy tratando de procesar algunos archivos XML utilizando la aplicación JAXB enviado en Java 7. Estoy usando estas versiones:procesamiento JAXB de secuencias XML

501 ~ % xjc -version 
xjc 2.2.4 
502 ~ %java -version   
java version "1.7.0_01" 
Java(TM) SE Runtime Environment (build 1.7.0_01-b08) 
Java HotSpot(TM) Server VM (build 21.1-b02, mixed mode) 

El decalaration problemática en el esquema XML es el siguiente :

<xsd:complexType name="CategorizeType"> 
    <xsd:complexContent> 
     <xsd:extension base="se:FunctionType"> 
      <xsd:sequence> 
       <xsd:element ref="se:LookupValue"/> 
       <xsd:element ref="se:Value"/> 
       <xsd:sequence minOccurs="0" maxOccurs="unbounded"> 
        <xsd:element ref="se:Threshold"/> 
        <xsd:element ref="se:Value"/> 
       </xsd:sequence> 
       <xsd:element ref="se:Extension" minOccurs="0" /> 
      </xsd:sequence> 
      <xsd:attribute name="thresholdBelongsTo" 
        type="se:ThresholdBelongsToType" use="optional"/> 
     </xsd:extension> 
    </xsd:complexContent> 
</xsd:complexType> 

Como se puede ver, hay dos ocurrencias explícitas de sí: Valor en el Tipo. Sin embargo, no detiene la compilación con xjc. Y si tengo una mirada en la clase Java generado para este tipo, puedo ver que es theoritically posible recuperar los elementos de

<xsd:sequence minOccurs="0" maxOccurs="unbounded"> 
    <xsd:element ref="se:Threshold"/> 
    <xsd:element ref="se:Value"/> 
</xsd:sequence> 

usando el siguiente método:

public List<Object> getThresholdAndValue() { 
    if (thresholdAndValue == null) { 
     thresholdAndValue = new ArrayList<Object>(); 
    } 
    return this.thresholdAndValue; 
} 

Por desgracia, si trato de los elementos de la lista, sólo pueden recuperar los elementos registrados como umbral en mi archivo XML, donde la instancia CategorizeType se define de la siguiente manera:

<Categorize thresholdsBelongTo="succeeding" fallbackValue="0"> 
    <LookupValue> 
     <ns3:ValueReference>OUI_EEE92</ns3:ValueReference> 
    </LookupValue> 
    <Value>0.3</Value> 
    <Threshold>30.0</Threshold> 
    <Value>0.4</Value> 
    <Threshold>40.0</Threshold> 
    <Value>0.45</Value> 
    <Threshold>45.0</Threshold> 
    <Value>0.5</Value> 
    <Threshold>50.0</Threshold> 
    <Value>0.55</Value> 
    <Threshold>55.0</Threshold> 
    <Value>0.6</Value> 
    <Threshold>60.0</Threshold> 
    <Value>0.7</Value> 
    <Threshold>70.0</Threshold> 
    <Value>0.8</Value> 
    <Extension> 
     <ExtensionParameter name="method">MANUAL</ExtensionParameter> 
    </Extension> 
</Categorize> 

Wh Al recuperar la lista, solo puedo ver los valores de Umbral.

¿Hago algo mal? ¿Es una limitación interna de Jaxb?

Tenga en cuenta que no puedo cambiar el esquema XML ...

EDIT:

acabo de correr xjc con la opción -v, y obtengo globalmente la misma salida. Con la verbosidad:

xjc -verbose se/2.0/All.xsd 
parsing a schema... 
[WARNING] java.net.SocketException: Unexpected end of file from server 
    line 23 of file:/home/alexis/crap/SE-Schema-2.0/ows/2.0/ows19115subset.xsd 

[WARNING] java.net.SocketException: Unexpected end of file from server 
    line 22 of file:/home/alexis/crap/SE-Schema-2.0/filter/2.0/filterCapabilities.xsd 

compiling a schema... 
[INFO] generating codee 
unknown location 

Sin ella:

xjc se/2.0/All.xsd 
parsing a schema... 
[WARNING] java.net.SocketException: Unexpected end of file from server 
    line 23 of file:/home/alexis/crap/SE-Schema-2.0/ows/2.0/ows19115subset.xsd 

[WARNING] java.net.SocketException: Unexpected end of file from server 
    line 22 of file:/home/alexis/crap/SE-Schema-2.0/ows/2.0/owsExceptionReport.xsd 

compiling a schema... 

La siguiente salida solo contiene el nombre y la ubicación de los archivos generados.

Olvidé decir que este xsd no se pudo compilar con el xjc incluido con Java 6. Se ha intentado por última vez con JAXB 2.1.10. No puedo reproducir este comportamiento ahora, como ahora. trabajar con Java 7.

Edit2:

acabo tratado de personalizar los binginds, como se sugiere en los comentarios. Mi archivo de enlace es el siguiente:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<jxb:bindings jxb:version="1.0" 
    xmlns:jxb="http://java.sun.com/xml/ns/jaxb" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" > 
    <jxb:bindings schemaLocation="schema.xsd" 
        node="//xsd:complexType[@name='CategorizeType']"> 
     <jxb:bindings 
        node="xsd:complexContent/xsd:extension/xsd:sequence/xsd:element[@ref='se:Value'][position()=1]"> 
      <jxb:property name="FirstValue"/> 
     </jxb:bindings> 
    </jxb:bindings> 
</jxb:bindings> 

El primer caso el valor es, en efecto reemplazado por un atributo firstValue en el código Java

@XmlElement(name = "Value", required = true) 
protected ParameterValueType firstValue; 
@XmlElements({ 
    @XmlElement(name = "Threshold", type = LiteralType.class), 
    @XmlElement(name = "Value", type = ParameterValueType.class) 
}) 
protected List<Object> thresholdAndValue; 

public ParameterValueType getFirstValue() { 
    return firstValue; 
} 
public void setFirstValue(ParameterValueType value) { 
    this.firstValue = value; 
} 
public List<Object> getThresholdAndValue() { 
    if (thresholdAndValue == null) { 
     thresholdAndValue = new ArrayList<Object>(); 
    } 
    return this.thresholdAndValue; 
} 

Por desgracia, todavía obtener el mismo resultado - Todavía no puedo ver mis valores en la lista devuelta por getThresholdAndValues ​​(). Todavía estoy explorando la forma en la personalización ...

+0

¿Cuáles son las anotaciones sobre el método 'getThresholdAndValue'? Esa es la parte interesante, no el cuerpo del método. – skaffman

+0

Ninguno. Las únicas anotaciones que puedo encontrar en esta clase se establecen en la clase y en sus atributos. Ninguno de ellos tiene un método ... – Agemen

+0

Problema interesante: ¿podría publicar el esquema completo? – davidfrancis

Respuesta

1

Creo que se necesita un elemento complexType alrededor

  <xsd:sequence minOccurs="0" maxOccurs="unbounded"> 
       <xsd:element ref="se:Threshold"/> 
       <xsd:element ref="se:Value"/> 
      </xsd:sequence> 

Se puede insertar una transformación XSLT para agregar un ComplexType a la definición del esquema antes de ejecutar xjc?

+0

Sí, eso podría ser una solución. Como nunca antes había usado XSLT, me llevará algo de tiempo :-p. Había identificado que esta lista era la clave de mi problema, y ​​que habría sido mucho más simple si se hubiera definido en un tipo complejo separado. Pero como no estoy acostumbrado a XSLT, no pensé en usarlo. Lo intentaré, ya que soy libre de personalizar la compilación del XML (incluso si no puedo tocar el XML). – Agemen

+0

Lo que me temo, sin embargo, es que no quiero tener que aplicar ninguna transformación a los archivos definidos usando este XSD. En consecuencia, tendré que poder leer una lista de umbral de valor, sin ningún elemento intermedio ... – Agemen

3

Actualización: Lo siento, tuve que renunciar a esto, simplemente no pude hacer que funcionara (¡sería mucho más fácil si pudiera cambiar su esquema!). Estaba usando el Codehaus JAXB maven plugin. Estoy bastante seguro de que es un conflicto provocado por los dos elementos de valor , que he tratado de corregir con una personalización xjb:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<jxb:bindings jxb:version="1.0" xmlns:jxb="http://java.sun.com/xml/ns/jaxb" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <jxb:bindings schemaLocation="../xsd/example.xsd" node="/xsd:schema"> 
     <jxb:schemaBindings> 
      <jxb:package name="com.example" /> 
      <jxb:nameXmlTransform> 
       <jxb:elementName suffix="Element"/> 
      </jxb:nameXmlTransform> 
     </jxb:schemaBindings> 
    </jxb:bindings> 
</jxb:bindings> 

Tenía absolutamente ningún efecto. Intenté <jxb:typeName suffix="Element"/>, y cambié el nombre de todas las clases de JAXB, así que supongo que hay un error con la característica jxb:elementName.

Post original:

he estado buscando en esto y yo soy capaz de replicar su problema.

Me tomé algunas libertades con su esquema para simplificar las cosas, pero todavía contiene los elementos esenciales. Esto es lo que he estado usando:

<?xml version="1.0" encoding="UTF-8"?> 
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns:se="http://com.example/example" 
     targetNamespace="http://com.example/example" 
    elementFormDefault="qualified"> 

    <xsd:element name="Categorize" type="se:CategorizeType" /> 

    <xsd:complexType name="FunctionType"> 
    </xsd:complexType> 

    <xsd:simpleType name="Value"> 
     <xsd:restriction base="xsd:string"/> 
    </xsd:simpleType> 

    <xsd:simpleType name="Threshold"> 
     <xsd:restriction base="xsd:string"/> 
    </xsd:simpleType> 

    <xsd:complexType name="CategorizeType"> 
     <xsd:complexContent> 
      <xsd:extension base="se:FunctionType"> 
       <xsd:sequence> 
        <xsd:element name="Value" type="se:Value" /> 
        <xsd:sequence minOccurs="0" maxOccurs="unbounded"> 
         <xsd:element name="Threshold" type="se:Threshold" /> 
         <xsd:element name="Value" type="se:Value" /> 
        </xsd:sequence> 
       </xsd:sequence> 
      </xsd:extension> 
     </xsd:complexContent> 
    </xsd:complexType> 
</xsd:schema> 

He quitado todos los elementos/atributos no relacionados con el tema, que se utiliza en lugar de name/typeref, y definido los tipos que faltan en su esquema proporcionado.

Mi clase JAXB CategorizeType generada se ve así:

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(name = "CategorizeType", propOrder = { 
    "value", 
    "thresholdAndValue" 
}) 
public class CategorizeType 
    extends FunctionType 
{ 

    @XmlElement(name = "Value", required = true) 
    protected String value; 
    @XmlElementRefs({ 
     @XmlElementRef(name = "Value", 
      namespace = "http://com.example/example", type = JAXBElement.class), 
     @XmlElementRef(name = "Threshold", 
      namespace = "http://com.example/example", type = JAXBElement.class) 
    }) 
    protected List<JAXBElement<String>> thresholdAndValue; 

    ... 
} 

Cuando Resolver referencia el código XML, mi Categorize.Value es 0.8 (en lugar de la 0.3 esperado), y los valores de cada ThresholdAndValue (todo en mi Strings caso) son 30.0, 40.0, 45.0, etc. Faltan 0.4, 0.45, etc.

Cuando elimino el primer elemento Value del esquema y luego se deshace, obtengo todos los valores esperados, ¡así que definitivamente hay un conflicto!

Sin embargo, cuando Marshall utilizando la siguiente configuración JAXB:

ObjectFactory factory = new ObjectFactory(); 
CategorizeType catType = factory.createCategorizeType(); 
catType.setValue("0.3"); 
JAXBElement<String> thresh = factory.createCategorizeTypeThreshold("30.0"); 
JAXBElement<String> threshVal = factory.createCategorizeTypeValue("0.4"); 
JAXBElement<String> thresh2 = factory.createCategorizeTypeThreshold("40.0"); 
JAXBElement<String> threshVal2 = factory.createCategorizeTypeValue("0.45"); 
catType.getThresholdAndValue().add(thresh); 
catType.getThresholdAndValue().add(threshVal); 
catType.getThresholdAndValue().add(thresh2); 
catType.getThresholdAndValue().add(threshVal2); 
JAXBElement<CategorizeType> element = factory.createCategorize(catType); 
// marshall to XML here! 

consigo la salida esperada:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<Categorize xmlns="http://com.example/example"> 
    <Value>0.3</Value> 
    <Threshold>30.0</Threshold> 
    <Value>0.4</Value> 
    <Threshold>40.0</Threshold> 
    <Value>0.45</Value> 
</Categorize> 

voy a seguir buscando en esto!

Cuestiones relacionadas