【问题标题】:Transforming file compliant with Xml Schema A into a file compliant with XML schema B using XSLT使用 XSLT 将符合 Xml 模式 A 的文件转换为符合 XML 模式 B 的文件
【发布时间】:2011-02-17 18:46:26
【问题描述】:

我已经搜索过这个问题,但是用语言来表达涉及 XSL 的问题似乎非常困难,所以我什么也没想到。

我的问题是这样的:

一家公司生产了一个应用程序,该应用程序使用 XML 文件来存储其“文档”。这些文件是针对架构版本 1.1 强制执行的

但是,该公司决定发布一个新版本的软件,该版本针对具有不同结构的新模式(模式 1.2)进行验证

为了让客户无缝地使用新版本,我们希望在打开文件时以编程方式将其符合 1.1 的文件转换为符合 1.2 的文件。理想情况下,我们使用 XSL 转换来做到这一点。

在这两种模式中,有些类型是相同的,有些类型有新的或重命名的成员,有些则存储在完全不同的结构中。因此,编写从一个到另一个的转换是相当乏味的,维护它更是如此。

如果能编写一种生成转换的转换,它可以将旧模式中未更改的类型匹配到新模式,并在它不能做的地方发出占位符元素(例如<xsl:message> 元素),那就太好了因此,为了提示开发人员在需要的地方手动编写自定义逻辑,并保证其他地方都兼容。

所以程序是这样的:

  • 针对 Schema 1.2 运行转换 A。这会生成变换 B;
  • 针对 Schema 1.1 运行转换 B。这会在可能的情况下将 Schema 1.2 与 Schema 1.1 匹配,生成转换 C;
  • Transform C 被开发人员用作骨架来编写从 instance 1.1 到 instance 1.2 的水密转换。

我已经通过实现它获得了一个公平的方法,但是 XSLT 1.0 的一些细节给我带来了问题。

转换 B 需要自动生成 <xsl:call-template> 语句,并将遇到的每个元素的类型名写入name 属性。然后,这将为每个 type 正确运行转换逻辑,以生成转换 C。

但是,call-template 似乎不接受任何 xpath 语法。它坚持name 必须只包含一个 NMTOKEN 和一个 NMTOKEN。从设计的角度来看,我可以理解这一点,但这很烦人,因为我想根据元素的类型而不是名称在元素上运行逻辑。我想在xsl:template match="element" 模板中声明call-template name="@type"。我的第一阶段确保存在一个匹配的命名模板来调用。

我不确定如何继续。有没有人尝试过这样的事情?是否有一些计算机科学的基本理论宣称在声明性语法中是不可能的? (希望不会!)

我希望我的解释清楚。如果没有,我会发布代码。

【问题讨论】:

  • 一个可能有用的解决方案是使用xsl:namespace-alias 从 XSLT 本身生成 XSLT 代码。因此,您将能够提供您通常无法在运行时执行的操作,例如从字符串评估 XPath 表达式。虽然dyn:evaluate 也是一种选择。
  • 我不相信有通用的方法来做到这一点。
  • @Tom W:我认为你正在用这种方法浪费时间。任何模式都不应该如此复杂(标准当然也不是)以至于它不会让您轻松编写从一个模式到另一个模式的转换。
  • @Alejandro: 我不知道是什么让你这么说。模式很少非常复杂,但它们很长。当我说手动保持转换很乏味时,我是根据经验说话的。此外,频繁的版本修改需要每次都用肉眼检查转换。
  • @John Saunders:我担心你可能弄错了。我已经通过实施看起来广泛适用的东西获得了公平的方法。我只是在处理细节问题,同时对陷阱和并发症提出一般要求。

标签: xml xslt schema transform


【解决方案1】:

首先,市场上有许多工具试图根据源和目标模式生成转换,并使用图形工具来定义它们之间的关系。就个人而言,我对这些工具没什么兴趣,但有些人似乎喜欢它们,所以试试看。示例可以在 XML Spy 和 Stylus Studio 等流行的 XML 工具中找到。

其次,为此尝试使用 xsl:call-template 似乎很奇怪。这显然是使用模板规则和 xsl:apply-templates 进行基于规则的转换的情况。基于元素类型的调度机制显然是应用模板而不是调用模板。在 XSLT 2.0 中,您可以直接使用具有格式规则的模式感知样式表来完成您的要求

<xsl:template match="element(*, type-name)">

其中 type-name 是模式中类型的名称。

【讨论】:

  • 感谢您的意见。出于某种原因,匹配模板对类型的适用性让我无法理解——而且我仍然不完全确定语法。我可以假设apply-templates select="./@type" 就足够了吗?我不知道为什么我没有得到这个。仅供参考,我在.Net 中,它不支持 XSLT 2.0。此外,我认为我正在探索的雇主不会容忍为使用 XSL 等开放标准的工具付费的想法。
  • 不幸的是,很难找到免费的模式感知 XSLT 处理器(或者通常是 XSLT 2.0 处理器)这一事实与现在许多公司希望软件是免费的这一事实直接相关。很遗憾,但我不会试图把它变成推销。
猜你喜欢
  • 2021-08-12
  • 2019-04-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-12
  • 1970-01-01
  • 2014-11-15
  • 2020-08-27
相关资源
最近更新 更多