XSD ファイルがあり、そこから C# および Java クラスも生成したいと考えています。
まず、クラスが存在する C# 名前空間に従って、XSD に名前空間を設定します。生成 (Microsoft ツールを使用) は正常に機能し、シリアライゼーションもうまく機能し、XSD に対してそれらを検証できます。完璧です。
今、JAXB で Java クラスを作成したいと考えています。問題は、作成されるクラスのパッケージ構造が C# のものとは異なることです。そこで、XSD 名前空間を Java のパッケージ構造に設定すると、正常に動作します。XML をシリアル化して検証できます。
今私の質問:これを解決する方法はありますか? (両方の生成ツールに 1 つの XSD を用意してください) 名前空間が実際に何のために必要なのかを理解していませんか?
ありがとうございました
編集:誤解があるようですので、例を追加しました
XSD: targetNamespace = "http://foo.bar/mySubNs/model"
- C# Modelnamespace: com.foo.mySubNs.model (XSD 名前空間に適合) 生成されたすべてのクラスは、MS codegen によって提供される同じ名前空間を持ちます
- Java Modelnamespace : com.foo.myOtherSubNs.model (XSD 名前空間とは異なります) 生成されたクラスには「C# 名前空間」が含まれます。その結果、クラスはコンパイルされません。
Java のコード生成中に名前空間を変更すると、クラスをコンパイルできます。ここまでは順調ですね。しかし、名前空間が異なるため、その Java クラスによって生成された XML を XSD に対して検証することはできません。
オブジェクトを Java でマーシャリングするには、次のように JAXB を使用します。
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"));
スキーマから Java クラスを構築するには、ant ビルド スクリプトで xjc-task を使用します。
<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>