如何在一个Java应用程序中处理不同版本的xsd文件?

时间:2009-11-10 10:06:51

标签: java xml xsd jaxb

事实

在我的java应用程序中,我必须同时处理具有不同模式版本(xsd文件)的XML文件。 XML文件的内容在不同的版本之间只有一点点的变化,所以我想主要使用相同的代码来处理它,并且只是根据所使用的模式的版本做一些案例distictions。

当前解决方案

现在我正在使用SAX解析器和我自己的ContentHandler解析XML文件,忽略架构版本,只检查我需要处理的标签是否存在。

可能的替代方案

我真的很想使用JAXB生成用于解析XML文件的类。这样我就可以从我的java代码中删除所有硬编码字符串(常量),并使用生成的类来处理。

问题(S)

  • 如何使用JAXB以统一的方式处理不同的架构版本?
  • 有更好的解决方案吗?

进度

我将架构版本编译为不同的包v1,v2和v3。现在我可以用这种方式创建Unmarshaller

JAXBContext jc = JAXBContext.newInstance( 
    v1.Root.class, v2.Root.class, v3.Root.class );
Unmarshaller u = jc.createUnmarshaller();

现在u.unmarshal( xmlInputStream );为我提供了与XML文件架构匹配的Root类。

接下来,我将尝试定义interface以访问模式的公共部分。 如果您以前做过类似的事情,请告诉我。与此同时,我正在阅读JAXB规范...

1 个答案:

答案 0 :(得分:6)

首先,您需要某种方法来识别适合特定实例文档的模式。您说文档具有schemaLocation属性,因此这是一个解决方案。但请注意,您必须专门配置解析器以使用此属性,并且恶意文档可以指定您无法控制的架构位置。相反,我建议获取属性值,并使用它在内部表中查找适当的模式。

接下来是访问数据。你没有说为什么你使用三种不同的模式。唯一合理的原因是不断发展的数据规范(即,模式代表相同数据的版本1,2和3)。如果这不是您的理由,那么您需要重新考虑您的设计。

如果您正在尝试支持不断发展的数据规范,那么您需要回答“如何处理缺少的数据”这一问题。这有几个答案:一个是维护代码的多个版本。通过重构常用功能,这不是一个坏主意,但它很容易变得不可维护。

另一种方法是使用单个代码库,以及包含规则的某种adapter对象。如果沿着这条路走下去,JAXB是错误的解决方案,因为它与模式相关联。你可以使用一个宽松的XML-> Java转换器:我相信XStream会起作用,我知道Practical XML的1.1版本会起作用(因为我写了它) - 尽管你我必须自己建造它。

另一个更好的替代方案,取决于模式的复杂性,是开发一组使用XPath来检索数据的对象。我可能会在架构的每个变体中使用包含每个字段的XPath表达式的“主”对象来实现。然后创建包含实例文档的DOM版本的轻量级“包装器”对象,并使用适合于模式的XPath。但请注意,这仅限于只读访问。