我有一个XSL样式表,它可以导入许多其他XSL样式表,并用于处理各种XML文件。我想检查一下导入的模板都没有冲突。
例如,我有一个导出import_one.xsl
和import_two.xsl
的样式表。
import_one.xsl
包含一个模板:
<xsl:template match="Foo">
One
</xsl:template>
和import_two.xsl
包含一个模板:
<xsl:template match="Foo">
Two
</xsl:template>
这两个模板都将匹配具有相同优先级的Foo
个元素,这是XSL处理器可以使用最后导入的模板恢复的错误。
对于给定的一组XML文件,我想检查是否会发生此类错误。
XSL样式表包含JavaScript函数并使用MSXSL节点集,这阻止我使用例如撒克逊人会在发生此类冲突时发出警告。 MSXSL处理器可以处理样式表,但不会发出警告。
我有什么选择?
答案 0 :(得分:0)
我认为您可能需要考虑编写一些简单的分析工具。这就是XSLT使用XML语法的事实真正开始带来好处:操纵XSLT代码比在大多数其他语言中操作代码要容易得多。如果您只需要了解相同的匹配模式,那么您可以使用类似
的2.0样式表来分析代码。<xsl:function name="f:all-modules" as="document-node()*">
<xsl:param name="root" as="document-node()"/>
<xsl:sequence select="$root, document($root/*/(xsl:include|xsl:import)/@href)/f:all-modules(.)"/>
</xsl:function>
<xsl:template name="duplicate-patterns">
<xsl:for-each-group select="f:all-modules(.)//xsl:template"
group-by="@match">
<xsl:if test="current-group()[2]">
<xsl:copy-of select="current-group()"/>
</xsl:if>
</xsl:for-each-group>
</xsl:template>
如果你想检测&#34;重叠&#34;有多个匹配的模式(例如para[1]
和para[@class='header']
)则无法通过静态分析完成,您需要进行一些动态处理。一种方法可能是将现有样式表转换为XSLT 2.0样式表,该样式表针对每个模式测试每个元素。您可以通过为每个模式生成唯一模式来完成此操作。它可能看起来像这样:
<xsl:template match="para[1]" mode="mode-7826">1</xsl:template>
<xsl:template match="*" mode="mode-7826"/>
<xsl:template match="para[@class='header']" mode="mode-7827" as="xs:integer">1</xsl:template>
<xsl:template match="*" mode="mode-7827"/>
<xsl:template match="/">
<xsl:for-each select="//*">
<xsl:variable name="matches">
<xsl:apply-templates select="." mode="mode-7826"/>
<xsl:apply-templates select="." mode="mode-7827"/>
<xsl:apply-templates select="." mode="mode-7828"/>
....
</xsl:variable>
<xsl:if test="string-length($matches) gt 1">
Conflict!!
</xsl:if>
</xsl:for-each>
</xsl:template>