XSLT异常处理技术
从XSLT2.0开始,据我所知(如果我错了,请纠正我),该语言中没有用于异常处理的本机机制 我有一些样式表,它们试图对输入文档的指定块进行一些处理,复制其他所有内容而不做任何更改。在开始为给定块生成输出之前,有一些罕见的异常情况是我无法轻易检测到的。它们非常罕见,当我遇到它们时,我所要做的就是取消对该块的处理,并将其原封不动地发出。某种类型的异常处理是正常的,但是XSLT没有太大帮助。我不想把Java或其他语言混入其中 我有一个下面描述的可行的解决方案,但我想知道其他的方法。你们都有更好的方法做这样的事情吗 这是我所说的那种情况的一个例子。这是一个输入文档:XSLT异常处理技术,xslt,exception-handling,Xslt,Exception Handling,从XSLT2.0开始,据我所知(如果我错了,请纠正我),该语言中没有用于异常处理的本机机制 我有一些样式表,它们试图对输入文档的指定块进行一些处理,复制其他所有内容而不做任何更改。在开始为给定块生成输出之前,有一些罕见的异常情况是我无法轻易检测到的。它们非常罕见,当我遇到它们时,我所要做的就是取消对该块的处理,并将其原封不动地发出。某种类型的异常处理是正常的,但是XSLT没有太大帮助。我不想把Java或其他语言混入其中 我有一个下面描述的可行的解决方案,但我想知道其他的方法。你们都有更好的方法做
<doc>
<block>some text, just copy.</block>
<!-- the following table should have B substituted for a -->
<table>
<tr><td>a</td><td>b</td><td>c</td></tr>
<tr><td>b</td><td>a</td><td>c</td></tr>
<tr><td>b</td><td>c</td><td>a</td></tr>
</table>
<block>some more text, just copy.</block>
<!-- the following table should be copied unaltered because of the presence of an x -->
<table>
<tr><td>a</td><td>b</td><td>c</td></tr>
<tr><td>b</td><td>a</td><td>x</td></tr>
<tr><td>b</td><td>c</td><td>a</td></tr>
</table>
</doc>
其输出为:
<doc>
<block>some text, just copy.</block>
<!-- the following table should have B substituted for a -->
<table>
<tr><td>B</td><td>b</td><td>c</td></tr>
<tr><td>b</td><td>B</td><td>c</td></tr>
<tr><td>b</td><td>c</td><td>B</td></tr>
</table>
<block>some more text, just copy.</block>
<!-- the following table should be copied unaltered because of the presence of an x -->
<table>
<tr><td>B</td><td>b</td><td>c</td></tr>
<tr><td>b</td><td>B</td><td>x</td></tr>
<tr><td>b</td><td>c</td><td>B</td></tr>
</table>
</doc>
一些文字,只是复制。
英国广播公司
英国广播公司
bcB
多点文字,就抄吧。
英国广播公司
bBx
bcB
它在第二张桌子上做了替换,这是我不想要的
我目前的解决方案是这样做:
标记
标记<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="table">
<xsl:variable name="result">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates mode="inner"/>
</xsl:copy>
</xsl:variable>
<xsl:choose>
<xsl:when test="$result//EXCEPTION">
<xsl:copy-of select="."/>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="$result"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template mode="inner" match="td">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:choose>
<xsl:when test=". = 'a'">
<xsl:value-of select="'B'"/>
</xsl:when>
<xsl:when test=". = 'x'">
<EXCEPTION/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:copy>
</xsl:template>
<xsl:template mode="inner" match="@*|node()" priority="-10">
<xsl:copy>
<xsl:apply-templates mode="inner" select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@*|node()" priority="-10">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
以及正确的输出:
<doc>
<block>some text, just copy.</block>
<!-- the following table should have B substituted for a -->
<table>
<tr><td>B</td><td>b</td><td>c</td></tr>
<tr><td>b</td><td>B</td><td>c</td></tr>
<tr><td>b</td><td>c</td><td>B</td></tr>
</table>
<block>some more text, just copy.</block>
<!-- the following table should be copied unaltered because of the presence of an x -->
<table>
<tr><td>a</td><td>b</td><td>c</td></tr>
<tr><td>b</td><td>a</td><td>x</td></tr>
<tr><td>b</td><td>c</td><td>a</td></tr>
</table>
</doc>
一些文字,只是复制。
英国广播公司
英国广播公司
bcB
多点文字,就抄吧。
abc
巴克斯
bca
如果您可以等待,则将出现try/catch表达式提供的示例非常简单,不需要任何异常处理功能
模式属性是您的朋友:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output omit-xml-declaration="yes"/>
<xsl:template match="node()|@*" mode="#default copy">
<xsl:copy>
<xsl:apply-templates select="node()|@*" mode="#current"/>
</xsl:copy>
</xsl:template>
<xsl:template match="table[tr/td[.='x']]">
<xsl:apply-templates select="." mode="copy"/>
</xsl:template>
<xsl:template match="td/text()[.='a']">B</xsl:template>
</xsl:stylesheet>
<doc>
<block>some text, just copy.</block>
<!-- the following table should have B substituted for a -->
<table>
<tr><td>a</td><td>b</td><td>c</td></tr>
<tr><td>b</td><td>a</td><td>c</td></tr>
<tr><td>b</td><td>c</td><td>a</td></tr>
</table>
<block>some more text, just copy.</block>
<!-- the following table should be copied unaltered because of the presence of an x -->
<table>
<tr><td>a</td><td>b</td><td>c</td></tr>
<tr><td>b</td><td>a</td><td>x</td></tr>
<tr><td>b</td><td>c</td><td>a</td></tr>
</table>
</doc>
<doc>
<block>some text, just copy.</block>
<!-- the following table should have B substituted for a -->
<table>
<tr><td>B</td><td>b</td><td>c</td></tr>
<tr><td>b</td><td>B</td><td>c</td></tr>
<tr><td>b</td><td>c</td><td>B</td></tr>
</table>
<block>some more text, just copy.</block>
<!-- the following table should be copied unaltered because of the presence of an x -->
<table>
<tr><td>a</td><td>b</td><td>c</td></tr>
<tr><td>b</td><td>a</td><td>x</td></tr>
<tr><td>b</td><td>c</td><td>a</td></tr>
</table>
</doc>
B
当此转换应用于提供的XML文档时:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output omit-xml-declaration="yes"/>
<xsl:template match="node()|@*" mode="#default copy">
<xsl:copy>
<xsl:apply-templates select="node()|@*" mode="#current"/>
</xsl:copy>
</xsl:template>
<xsl:template match="table[tr/td[.='x']]">
<xsl:apply-templates select="." mode="copy"/>
</xsl:template>
<xsl:template match="td/text()[.='a']">B</xsl:template>
</xsl:stylesheet>
<doc>
<block>some text, just copy.</block>
<!-- the following table should have B substituted for a -->
<table>
<tr><td>a</td><td>b</td><td>c</td></tr>
<tr><td>b</td><td>a</td><td>c</td></tr>
<tr><td>b</td><td>c</td><td>a</td></tr>
</table>
<block>some more text, just copy.</block>
<!-- the following table should be copied unaltered because of the presence of an x -->
<table>
<tr><td>a</td><td>b</td><td>c</td></tr>
<tr><td>b</td><td>a</td><td>x</td></tr>
<tr><td>b</td><td>c</td><td>a</td></tr>
</table>
</doc>
<doc>
<block>some text, just copy.</block>
<!-- the following table should have B substituted for a -->
<table>
<tr><td>B</td><td>b</td><td>c</td></tr>
<tr><td>b</td><td>B</td><td>c</td></tr>
<tr><td>b</td><td>c</td><td>B</td></tr>
</table>
<block>some more text, just copy.</block>
<!-- the following table should be copied unaltered because of the presence of an x -->
<table>
<tr><td>a</td><td>b</td><td>c</td></tr>
<tr><td>b</td><td>a</td><td>x</td></tr>
<tr><td>b</td><td>c</td><td>a</td></tr>
</table>
</doc>
一些文字,只是复制。
abc
美国银行
bca
多点文字,就抄吧。
abc
巴克斯
bca
生成所需的正确结果:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output omit-xml-declaration="yes"/>
<xsl:template match="node()|@*" mode="#default copy">
<xsl:copy>
<xsl:apply-templates select="node()|@*" mode="#current"/>
</xsl:copy>
</xsl:template>
<xsl:template match="table[tr/td[.='x']]">
<xsl:apply-templates select="." mode="copy"/>
</xsl:template>
<xsl:template match="td/text()[.='a']">B</xsl:template>
</xsl:stylesheet>
<doc>
<block>some text, just copy.</block>
<!-- the following table should have B substituted for a -->
<table>
<tr><td>a</td><td>b</td><td>c</td></tr>
<tr><td>b</td><td>a</td><td>c</td></tr>
<tr><td>b</td><td>c</td><td>a</td></tr>
</table>
<block>some more text, just copy.</block>
<!-- the following table should be copied unaltered because of the presence of an x -->
<table>
<tr><td>a</td><td>b</td><td>c</td></tr>
<tr><td>b</td><td>a</td><td>x</td></tr>
<tr><td>b</td><td>c</td><td>a</td></tr>
</table>
</doc>
<doc>
<block>some text, just copy.</block>
<!-- the following table should have B substituted for a -->
<table>
<tr><td>B</td><td>b</td><td>c</td></tr>
<tr><td>b</td><td>B</td><td>c</td></tr>
<tr><td>b</td><td>c</td><td>B</td></tr>
</table>
<block>some more text, just copy.</block>
<!-- the following table should be copied unaltered because of the presence of an x -->
<table>
<tr><td>a</td><td>b</td><td>c</td></tr>
<tr><td>b</td><td>a</td><td>x</td></tr>
<tr><td>b</td><td>c</td><td>a</td></tr>
</table>
</doc>
一些文字,只是复制。
英国广播公司
英国广播公司
bcB
多点文字,就抄吧。
abc
巴克斯
bca
如果真的需要异常(我们还需要看到一个好的用例),它们将成为标准的我相信他们已经决定下一版本的XSLT(以及XPATH和XQuery)将是“3.0”版本。我等不及了,但我可以稍后再谈。这也让我看到了Saxon的扩展(不可否认,我早就应该这么做了)。我使用的是HE版本,但EE版本也有类似的机制()。这不值得升级,但很高兴知道。这里没有例外。这就是无副作用陈述范式的美妙之处。所有可能会产生副作用的功能都有一个可行的测试。对于不同的元素模式,这里有一个不同的过程。正如您所写的,只要有可能使用模式匹配,就去做。在某些情况下,这可能是困难的或不是最佳的。然后在临时结果树上进行两步过程,就像你的例子一样。@Steven Ourada、@Nick Jones和@Alejandro:好问题(+1)。关于一个不需要try/catch机制的非常简单的解决方案,请参见我的答案:)对于异常可能非常有用的非常复杂的情况,您必须等待XSLT 3.0。我肯定您注意到,我特别提到我的测试用例在这里非常简化。对不起,我不能告诉你整个真实情况;所有的细节都会模糊基本概念。你只需要相信我,我相信例外情况会对我有用:-)。有时候最好的解决方案不是概念上最完美的,而是最简单的…@Steven Ourada:是的,我不得不相信你。最好是更具说服力,并给出这样的例子