Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
XSLT异常处理技术_Xslt_Exception Handling - Fatal编程技术网

XSLT异常处理技术

XSLT异常处理技术,xslt,exception-handling,Xslt,Exception Handling,从XSLT2.0开始,据我所知(如果我错了,请纠正我),该语言中没有用于异常处理的本机机制 我有一些样式表,它们试图对输入文档的指定块进行一些处理,复制其他所有内容而不做任何更改。在开始为给定块生成输出之前,有一些罕见的异常情况是我无法轻易检测到的。它们非常罕见,当我遇到它们时,我所要做的就是取消对该块的处理,并将其原封不动地发出。某种类型的异常处理是正常的,但是XSLT没有太大帮助。我不想把Java或其他语言混入其中 我有一个下面描述的可行的解决方案,但我想知道其他的方法。你们都有更好的方法做

从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:是的,我不得不相信你。最好是更具说服力,并给出这样的例子