c# - Un XSD, dos herramientas de generación de código, dos espacios de nombres
java jaxb (2)
Tengo un archivo XSD, del cual también quiero generar clases C # y Java.
Primero configuré el espacio de nombres en el XSD de acuerdo con mi espacio de nombres C # donde residen mis clases. La generación (con las herramientas de Microsoft) funciona bien y también la serialización funciona muy bien y puedo validarlos contra el XSD, perfecto.
Ahora quiero crear clases Java con JAXB. El problema es que las clases que van a crearse tienen una estructura de paquete diferente a la de C #. Entonces, cuando configuro el espacio de nombres XSD para la estructura del paquete de java, funciona bien. Puedo serializar y validar el XML.
Ahora mi (s) pregunta (s): ¿Hay alguna manera de resolver esto? (Tenga un XSD para ambas herramientas de generación) ¿No entiendo por qué se necesita realmente el espacio de nombres?
Gracias
Editar: Dado que parece ser que hay un malentendido, agregué un ejemplo
XSD: targetNamespace = "http://foo.bar/mySubNs/model"
- Espacio de nombre de modelo C #: com.foo.mySubNs.model (que se ajusta al espacio de nombre XSD) todas las clases generadas tendrán el mismo espacio de nombres proporcionado a través del codegen MS
- Java Modelnamespace: com.foo.myOtherSubNs.model (que difiere del espacio de nombre XSD) las clases generadas tendrán el "espacio de nombres C #". Como resultado, las clases no se compilarán.
Si cambio el espacio de nombres durante la generación de código para java, puedo compilar las clases. Hasta aquí todo bien. Pero no podré validar el XML generado por las clases java contra el XSD, ya que el espacio de nombres es diferente.
Para ordenar mis objetos en Java, uso JAXB así:
ValidationEventCollector validationCollector = new ValidationEventCollector();
SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = schemaFactory.newSchema(new File ("my/schema/location"));
// JAXB_CONTEXT is just an instance of "JAXBContext"
Marshaller marshaller = JAXB_CONTEXT.createMarshaller();
marshaller.setSchema(schema);
marshaller.setEventHandler(validationCollector);
marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
JAXBElement<MyClass> root = new JAXBElement<MyClass> ( new QName(MyClass.class.getPackage().getName(),"MyClass"),MyClass.class, node);
marshaller.marshal(root, new File("output/Path/obj.xml"));
Para construir mis clases Java desde el esquema, utilizo una tarea xjc en una secuencia de comandos de construcción ant:
<xjc destdir="${dir.src.gen}" removeOldOutput="no" extension="true">
<schema dir="${dir.schema}" includes="${file.schema}"/>
<binding dir="${dir.schema}" includes="*.xjb"/>
<produces dir="${dir.src.gen}" includes="**/*.java"/>
</xjc>
Debe elegir el modelo que sea el principal: XSD, C # o código Java. Una vez que haga esa elección, debe dejar que los otros dos varíen como sea posible. La mejor opción sería hacer de su XSD el modelo de referencia, generar el código en ambos idiomas con sus respectivas herramientas y simplemente aceptar los resultados.
También puede intentar elegir el espacio de nombres XML para que el código en ambos extremos sea satisfactorio, pero no intente forzar nada hasta la última letra. Así no es como debe funcionar.
El espacio de nombres XSD no tiene que coincidir con la estructura del paquete, al menos no en Java. Al generar las clases con JAXB, solo proporcione el paquete en el que desea colocar las clases.