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

标签 c++ xml xslt xsd

我目前正在用 C++ 设计一个特殊用途的应用程序,它必须处理随不断发展的 XSD 方案 而来的 XML 文件。

  • 此应用程序将需要在未来很长一段时间内得到支持,很可能需要支持更新版本的 XML 文件。

主要挑战是:input-XML 文件带有基本相似的 XSD 方案 (它们都是同一个配置数据定义标准的不同版本),只是在结构甚至命名上都不同。

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

事实

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

到目前为止,已做出以下考虑:

为每个版本使用数据绑定(bind)

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

  • 导致巨大(非常大)的代码库
  • 需要生成类的接口(interface)
  • 面向 future ?

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

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

  • 只读!

使用 XSLT 转换旧 XML

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

  • 需要为每个版本创建一个 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
    
  • 您认为上述哪种方法效果最好?

  • 还有其他选择吗?

最佳答案

回想起来,事实证明以下方法足以满足我 99% 的需求:

  1. 方法:“版本跳跃”

    对于需要支持的给定 XML 文件/XSD 方案的每个版本,已创建 XSL 转换以将给定输入文件转换为下一个版本,最后是 XML-C++ 数据绑定(bind)使用 Code Synthesis XSDe 生成。

    每当需要支持新版本时,只需将一个 XSLT 样式表添加到预处理器,代码生成基本上是自动化的 - 每个版本都有几个单元测试以确保支持新版本不会'打破对遗留文件的支持。

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

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

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

    每当需要支持新版本时,只需将一个新的 XSLT 文件添加到预处理器中,生成的输出文件在所有版本中保持相同。

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

关于c++ - 在 C++ 中支持基于模式的不断发展的 XML 的技术,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28742693/

相关文章:

c++ - 如何在 C++ 中将字符串转换为 double 值?

java - 为 XML 上的自定义 View 设置标签缩写

php - 在 XPath 中实现条件

c++ - QByteArray 到 Int 的转换

C++ 字符串 : [] vs. *

c++ - 为什么内置类型和类在不使用时会受到不同对待?

c# - 在 .NET XmlDocument 中移动 "a child up"的最佳方法是什么?

list - XSL-FO-如何在两个列表 block 中继续编号?

linux - 如何在 .xsl 文件中打印这个?

xslt - 引用 xsl 中的属性值 :param xsl:if test condition