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

tan*_*ens 13 java xml xsd jaxb

事实

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

现行解决方案

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

可能的选择

我真的很想使用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();
Run Code Online (Sandbox Code Playgroud)

现在u.unmarshal( xmlInputStream );给我一个Root匹配XML文件架构的包中的类.

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

kdg*_*ory 6

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

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

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

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

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