在C ++中支持基于模式的XML发展的技术

时间:2015-02-26 12:37:32

标签: c++ xml xslt xsd

我目前正在设计 C ++ 中的专用应用程序,该应用程序必须处理不断发展的XSD方案附带的XML文件。

  • 将来需要支持此应用程序,很可能需要支持更新版本的XML文件。

主要的挑战是:输入XML文件带有基本相似的XSD方案 (它们都是配置数据相同定义标准的不同版本),但在结构和命名方面都有所不同。

  • 现在不需要文件中包含的所有数据,这可能会改变!
  • 目前只需要在应用程序启动时读取数据,这可能会发生变化!
  • 目前只需要读取数据,而不是回写,这可能会改变!

事实

  • XML文件可能大到200MB。
  • XSD方案有500多行纯代码(无评论)。
  • 现在我需要支持至少3个不同的版本(10 +以上)。
  • 将要使用的XML解析器必须是名称空间感知。
  • 版本的更改日志存在,但遗憾的是不完整且非常精确。

到目前为止,已经进行了以下考虑:

为每个版本使用数据绑定

Code Synthesis XSD提供了一个很好的基于DOM / SAX的解析器和数据绑定生成器。

  • 带来了巨大的(非常大的)代码库
  • 所需生成类的接口
  • 面向未来的?

将SAX解析器与基于版本的处理程序一起使用

通过使用像Apache Xerxes这样的sax-parser,特定于版本的代码可以放在sax-callback-handler中。 这些回调处理程序可以通过'VersionReaderFactory'隐藏,该VersionReaderFactory为特定版本的XML文件返回正确的处理程序。 处理程序会将数据填充到包含必要配置数据的通用数据类中。

  • 只读!

使用XSLT转换旧XML

Altova提供了一个很好的XSLT处理器,可用于将旧版本的XML定义的配置数据转换为最新版本。 执行此转换后,可以使用“简单”数据绑定来访问数据,因为只有一个版本需要支持。

  • 需要为每个版本创建一个XSL转换。
  • 创建转换代码容易出错。
  • 目前还不清楚是否所有版本的所有实体都可以进行转换。 (不完整的更改日志)

使用XPATH

将XML作为基础格式,XPATH将是查询数据的自然选择。 'home-brew-parser'可以使用一些'VersionReaderFactory',它为特定版本的XML文件返回一组预定义的XPATH查询。 这个'home-brew-parser'将使用必要的配置数据填充通用数据类。

  • 可以连续扩展以满足要求
  • 只读!

问题

  • 应用程序的哪个部分应该是版本感知的?

      XML             |    Parser               |    Application
      close to data   | beneath the application | in the application
    
  • 您认为哪种方法最适合?

  • 还有其他选择吗?

1 个答案:

答案 0 :(得分:1)

回顾起来,以下方法足以满足我99%的需求:

  1. 方法:“版本跳变”

    对于需要支持的给定XML文件/ XSD-schemes的每个版本,已经创建了XSL-Transformation来将给定的输入文件转换为下一个版本,最后是XML-C ++数据绑定,如下所示:是使用Code Synthesis XSDe生成的。

    每当需要支持新版本时,只需在预处理器中添加一个XSLT样式表,并且代码生成基本上是自动的-每个版本都有几个UnitTest,以确保支持新版本不会不会破坏对旧文件的支持。

  2. 方法:“提取所需数据”

    对于需要支持的给定版本的XML文件/ XSD-shemes的每个版本,已创建XSL转换,以将给定的输入文件转换为仅包含所需数据的另一个文件类型。

    通过使用这种方法,可以使用简单的XML方案甚至众所周知的键值存储文件类型(例如json)来收集所需数据。

    每当需要支持新版本时,只需将一个新的XSLT文件添加到预处理器中,结果输出文件在所有版本中都将保持不变。

这两种方法的预处理器都可以使用XLST 2+创建,并在Saxon HE上运行。