0

我有一个 XSD 文件,我也想从中生成 C# 和 Java 类。

我首先根据我的类所在的 C# 命名空间在 XSD 中设置命名空间。生成(使用 Microsoft 工具)运行良好,序列化也运行良好,我可以针对 XSD 验证它们 - 完美。

现在我想用 JAXB 创建 java 类。问题是要创建的类与 C# 中的类具有不同的包结构。所以当我将 XSD 命名空间设置为 java 的包结构时,它工作正常。我可以序列化和验证 XML。

现在我的问题是:有没有办法解决这个问题?(两个生成工具都有一个 XSD)我是否缺乏对命名空间实际需要什么的理解?

谢谢

编辑:由于似乎存在误解,我添加了一个示例

XSD: targetNamespace = "http://foo.bar/mySubNs/model"

  • C# 模型命名空间:com.foo.mySubNs.model(适合 XSD 命名空间)所有生成的类都将具有通过 MS 代码生成提供的相同命名空间
  • Java 模型命名空间:com.foo.myOtherSubNs.model(不同于 XSD 命名空间)生成的类将具有“C# 命名空间”。结果这些类将无法编译。

如果我要在 java 代码生成期间更改命名空间,我可以编译这些类。到现在为止还挺好。但是我将无法针对 XSD 验证该 java 类生成的 XML,因为名称空间不同。

为了在 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>
4

2 回答 2

1

XSD 命名空间不必匹配包结构,至少在 Java 中不是。使用 JAXB 生成类时,只需提供要将类放入的包。

于 2012-07-16T11:21:35.280 回答
0

您必须选择哪种模型是主要模型:XSD、C# 或 Java 代码。一旦你做出了选择,你必须让其他两个尽可能地变化。最好的选择是将您的 XSD 作为参考模型,使用各自的工具生成两种语言的代码,然后接受结果。

您也可以尝试选择 XML 名称空间,以使两端的代码都令人满意,但不要尝试将任何内容强制到最后一个字母。这不是它的工作方式。

于 2012-07-16T11:18:42.610 回答