2010-12-09 34 views
46

Usando JAXB para generar clases de enlace XML.JAXB - La propiedad "Valor" ya está definida. Utilice <jaxb: property> para resolver este conflicto

El esquema se basa en un conjunto de archivos XML antiguas, e incluye este fragmento:

<xs:complexType name="MetaType"> 
    <xs:simpleContent> 
     <xs:extension base="xs:string"> 
      <xs:attribute type="xs:string" name="Name" /> 
      <xs:attribute type="xs:string" name="Scheme" /> 
      <xs:attribute type="xs:string" name="Value" /> 
     </xs:extension> 
    </xs:simpleContent> 
</xs:complexType> 

el 'valor' conflictos de atributos con la propiedad 'valor' de xs:string, y la generación de código falla con el de error:

com.sun.istack.SAXParseException2: Property "Value" is already defined. Use &lt;jaxb:property> to resolve this conflict. 

Respuesta

54

La respuesta está en hacer uso de los enlaces de JAXB (site-template.xjb):

<bindings xmlns="http://java.sun.com/xml/ns/jaxb" 
      xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance" 
      xmlns:xs="http://www.w3.org/2001/XMLSchema" 
      version="2.1"> 
    <bindings schemaLocation="site-template.xsd" version="1.0"> 
     <!-- Customise the package name --> 
     <schemaBindings> 
      <package name="com.example.schema"/> 
     </schemaBindings> 

     <!-- rename the value element --> 
     <bindings node="//xs:complexType[@name='MetaType']"> 
      <bindings node=".//xs:attribute[@name='Value']"> 
       <property name="ValueAttribute"/> 
      </bindings> 
     </bindings> 
    </bindings> 
</bindings> 

Las expresiones XPath ubican los nodos y los renombran, evitando así el conflicto de nombres.

Usando este archivo XML de enlaces, la clase Java generada termina teniendo el getValueAttribute() deseado (así como el getValue()).

+2

Tuve este problema también y esta respuesta lo resolvió, gracias! Me gustaría añadir que si haces la generación de la clase Java con el plugin Maven jaxb, puedes poner el archivo xjb en el mismo directorio de recursos que el archivo XSD real. – Kaitsu

+0

¿Se puede usar esta solución para XSD remotos de alguna manera? Me estoy poniendo "no es parte de esta compilación". error. Gracias. – tomasb

+3

¿Dónde debería colocar este archivo 'site-template.xjb'? – Andremoniy

1

Tuve un problema al usar la solución con Eclipse (probé con Helios SR1 y Juno SR1) y CXF 2.6.3. La solución fue similar a lo que dice Kaitsu. A saber, el nuevo> Asistente de servicio web de Eclipse copia el wsdl en el contenido web foldre/wsdl. Tuve que colocar el wsdl y el archivo vinculante allí. De lo contrario, el archivo de enlace arrojó el error "no es parte de esta compilación".

No pude usar un esquema en línea en el WSDL, pero sí trabajó con un esquema externo como en la respuesta # 1.

Estoy usando la opción de configuración de punto final CXF Servlet. En mi WSDL que tengo:

<wsdl:port binding="axis2:ConverterSOAP12Binding" name="ConverterSOAP12port_http"> 
    <soap12:address location="http://localhost/Converter/services/Converter"/> 
</wsdl:port> 

El asistente genera esto en mi web.xml, que funciona bien:

<servlet-mapping> 
    <servlet-name>cxf</servlet-name> 
    <url-pattern>/services/*</url-pattern> 
</servlet-mapping> 

Pero poner esto en cxf-servlet.xml:

<jaxws:endpoint xmlns:tns="http://wtp" id="converterporttype" 
implementor="wtp.ConverterPortTypeImpl" wsdlLocation="wsdl/Converter.wsdl" 
endpointName="tns:ConverterSOAP12port_http" serviceName="tns:Converter" 
address="/ConverterSOAP12port_http"> 
    <jaxws:features> 
    <bean class="org.apache.cxf.feature.LoggingFeature" /> 
    </jaxws:features> 
</jaxws:endpoint> 

Tuve que cambiar la dirección a la URL completa, como esta:

address="http://localhost:8080/Converter/services/Converter"> 
0

Este archivo de enlaces mencionado en la otra respuesta no funcionó para mí con CXF 3.0.0. Aviso ese espacio de nombres jaxb tiene un elemento "fijaciones" y también lo hacen los jaxws de espacio de nombres, por lo que es necesario declararlas:

<?xml version="1.0" encoding="UTF-8"?> 
<bindings xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
      xmlns="http://java.sun.com/xml/ns/jaxws" 
      xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" 
      xmlns:xs="http://www.w3.org/2001/XMLSchema" 
      wsdlLocation="mesh.wsdl" > 
    <bindings node="wsdl:definitions/wsdl:types/xs:schema[..."> 
     <jaxb:bindings node="./xs:element[@name='Profiles']"> 
      <jaxb:property name="ProfilesElement"/> 
     </jaxb:bindings> 
    </bindings> 
</bindings> 

En mi caso, el esquema ya estaba dentro del WSDL así que no hay que especificar la atributo schemaLocation.

+0

Esta es la única respuesta aquí que incluye' jaxb: property', pero no entiendo cómo la respuesta aquí se relaciona con el resto del archivo. Por un lado, no veo ninguna etiqueta 'bindings' en el archivo WSDL que estoy tratando de corregir. – JohnK

+1

Este XML va en un archivo .xjb. Esta otra pregunta tiene un ejemplo: https://stackoverflow.com/questions/23961421 –

5

vez después de crear el archivo xxxx.xjb de nombre de atributo duplicado "valor" (es duplicado por defecto 'valor' proporcionado por JAXB) como a continuación, ejecutar comandos XJC para crear objetos JAXB

xjc -p "com .track.doc" -d "C: \ JAXBDocuments \ prasam \ Desktop \ JAXB_me \ DealerTrace" appSamp.xsd -b xxxx.xjb

appSmp.xsd: -

<xsd:complexType name="range"> 
    <xsd:simpleContent> 
     <xsd:extension base="xsd:string"> 
      <xsd:attribute name="value" type="xsd:string"/> 
     </xsd:extension> 
    </xsd:simpleContent>   
</xsd:complexType> 

xxxx.xjb: -

<?xml version="1.0" encoding="UTF-8"?> 
<bindings xmlns="http://java.sun.com/xml/ns/jaxb" 
      xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance" 
      xmlns:xs="http://www.w3.org/2001/XMLSchema" 
      version="2.1"> 
    <bindings schemaLocation="appSmp.xsd" version="1.0"> 

     <schemaBindings> 
      <package name="com.track.doc"/> 
     </schemaBindings>  
     <bindings node="//xs:complexType[@name='range']"> 
      <bindings node=".//xs:attribute[@name='value']"> 
       <property name="valueAttribute"/> 
      </bindings> 
     </bindings> 
    </bindings> 
</bindings> 
9

Si desea evitar la creación/modificación de un archivo de enlaces JAXB, y no le importa anotar su XSD, puede añadir el JXB : propiedad anotación a la definición de su atributo, por ejemplo:

<xs:complexType name="MetaType"> 
    <xs:simpleContent> 
     <xs:extension base="xs:string"> 
      <xs:attribute type="xs:string" name="Name" /> 
      <xs:attribute type="xs:string" name="Scheme" /> 
      <xs:attribute type="xs:string" name="Value"> 
       <!-- rename property generated by JAXB (avoiding "Value" name conflict) --> 
       <xs:annotation> 
        <xs:appinfo> 
         <jxb:property name="valueAttribute"/> 
        </xs:appinfo> 
       </xs:annotation> 
      </xs:attribute> 
     </xs:extension> 
    </xs:simpleContent> 
</xs:complexType> 

con el anuncio adecuado ditions a la etiqueta xs: schema:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
      xmlns:jxb="http://java.sun.com/xml/ns/jaxb" 
      jxb:version="2.1"> 
+0

¡Gracias! Me salvaste el día :) –

+1

Esto fue mucho mejor para mí. La respuesta aceptada requiere una configuración que no puedo gestionar. ¡Solo quería que funcionara! – absmiths

+0

creo que esta respuesta sería más adecuada para ser una respuesta adecuada a la pregunta –