我已经搜索过这个问题了,但用语言来表达涉及XSL的问题似乎非常难以实现,所以我什么也没想出来。
我遇到的问题是:
公司生成一个使用XML文件存储其“文档”的应用程序。这些文件是针对架构版本1.1
强制实施的然而,该公司决定发布一个新版本的软件,该软件针对具有不同结构的新模式进行验证,模式1.2
为了让客户无缝使用新版本,我们希望以编程方式将符合1.1的文件转换为文件打开时的1.2合规性。理想情况下,我们使用XSL Transformation进行此操作。
在这两种模式中,某些类型是相同的,某些类型具有新的或重命名的成员,而某些类型存储在完全不同的结构中。因此,将转换从一个转换为另一个转换是相当繁琐的,并且更加保持它。
编写一种变换生成变换会很好,它可以匹配从旧模式到新模式的未更改类型,并发出占位符元素(例如<xsl:message>
元素),无论它在哪里'这样做是为了提示开发人员在需要的地方手工编写自定义逻辑,并保证其他地方都符合要求。
所以程序如下:
我已经通过实现这一点得到了公平的方式,但是XSLT 1.0的一些细节导致了我的问题。
转换B需要自动生成<xsl:call-template>
语句,其中每个元素的类型名称都被标记到name
属性中。然后,这将正确运行每个类型的转换逻辑,以生成转换C.
但是,call-template
似乎不接受任何xpath语法。它坚持认为name
必须仅包含NMTOKEN和NMTOKEN。我从设计的角度来理解这一点,但它非常令人恼火,因为我想根据元素的类型而不是它的名称来运行逻辑。我想在call-template name="@type"
模板中说明xsl:template match="element"
。我的第1阶段确保存在匹配的命名模板以进行调用。
我不知道该怎么办。以前有人试过这样的事吗?是否存在一些计算机科学的基本理论,它声明在声明性语法中是不可能的? (我希望不是!)
我希望我的解释清楚。如果没有,我会发布代码。
答案 0 :(得分:1)
首先,市场上有许多工具试图基于源和目标模式生成转换,并使用图形工具来定义它们之间的关系。就个人而言,我对这些工具一点兴趣,但有些人似乎喜欢它们,所以试一试。示例可以在流行的XML工具中找到,例如XML Spy和Stylus Studio。
其次,尝试使用xsl:call-template似乎很奇怪。很明显,使用模板规则和xsl:apply-templates进行基于规则的转换。基于元素类型的调度机制显然是apply-templates而不是call-template。在XSLT 2.0中,您可以直接使用具有表单规则的模式感知样式表来执行您所要求的内容
<xsl:template match="element(*, type-name)">
其中type-name是架构中类型的名称。