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

事实

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

当前解决方

现在我使用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类.

接下来,我将尝试定义一个接口来访问模式的公共部分.如果你以前这样做过,请让我知道.同时我正在阅读JAXB规范…

解决方法

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

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

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

另一种方法是使用单个代码库,以及包含您的规则的某种类型的adapter对象.如果你走这条路,JAXB是一个错误解决方案,因为它与一个架构有关.您可能可以使用一个允许的XML-> Java转换器:我相信XStream将会工作,而且我知道Practical XML的1.1版本将会工作(自从我写了) – 尽管你必须自己构建它.

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

相关文章

HashMap是Java中最常用的集合类框架,也是Java语言中非常典型...
在EffectiveJava中的第 36条中建议 用 EnumSet 替代位字段,...
介绍 注解是JDK1.5版本开始引入的一个特性,用于对代码进行说...
介绍 LinkedList同时实现了List接口和Deque接口,也就是说它...
介绍 TreeSet和TreeMap在Java里有着相同的实现,前者仅仅是对...
HashMap为什么线程不安全 put的不安全 由于多线程对HashMap进...