一个模板打破另一个模板,即使它不匹配

时间:2015-03-18 02:47:31

标签: xml xslt

我对XSLT很新,并且对一个模板对我的转换产生的明显影响感到困惑,即使它不应该与任何东西匹配。

如果我有以下xsl文件:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8"/>

<xsl:template match="/">
    <xsl:apply-templates/>
</xsl:template>

<xsl:template match="input">
    <output>
        <xsl:call-template name="flattenText">
            <xsl:with-param name="node" select="current()"></xsl:with-param>
        </xsl:call-template>
    </output>
</xsl:template>

<xsl:template name="flattenText">
    <xsl:param name="node"/>
    <xsl:for-each select="$node/node()">
        <xsl:if test="self::text()">
            <xsl:value-of select="string(.)"/>
        </xsl:if>
        <xsl:if test="self::*">
            <xsl:call-template name="flattenText">
                <xsl:with-param name="node" select="."/>
            </xsl:call-template>
        </xsl:if>
    </xsl:for-each>
</xsl:template>

并在此输入上运行:

<?xml version="1.0" encoding="UTF-8"?>
<root>
<input>This <span class="blah">text</span> should be flattened.</input>
</root>

我得到了这个输出,我期待:

<?xml version="1.0" encoding="UTF-8"?>
<output>This text should be flattened.</output>

但是,如果我将此模板添加到XSL文件的底部:

<xsl:template match="span[@class = 'yuk']">
    <span>
        <xsl:attribute name="class">poo</xsl:attribute>
        <xsl:apply-templates />
    </span>
</xsl:template>

我明白了:

<?xml version="1.0" encoding="UTF-8"?>
<output>This  should be flattened.</output>

跨度的内容消失了,即使1)我没有在我看到的任何地方应用该模板,2)它甚至不应该匹配输入中的span,因为它有类“blah”和模板应该只匹配“yuk”类。

谁能告诉我发生了什么以及如何解决这个问题?我必须犯一些愚蠢的错误。

我正在使用Oxygen XML Editor 16.1中的JAXP(com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl)转换器,但我在Eclipse中遇到了同样的问题。 Saxon 6.5.5可以使用,但我不能将它用于我的项目。

非常感谢任何帮助!

更新:

我感谢大家的帮助并尝试重现我的问题。我的同事能够重现它,所以我仍然认为某些事情确实是错误的。如果有人感兴趣,这里有一些关于我的情况的信息:

  • Windows 7企业版,64位,Service Pack 1
  • java -version:java version“1.8.0_31” Java(TM)SE运行时环境(版本1.8.0_31-b13) Java HotSpot(TM)64位服务器VM(版本25.31-b07,混合模式)
  • 当我在Oxygen中运行JAXP转换时,我收到此警告:“ [JAXP]警告:'org.apache.xerces.jaxp.SAXParserImpl:无法识别属性'http://javax.xml.XMLConstants/property/accessExternalDTD'。'“我不知道这是否重要。

我正在开发一个设置为使用JAXP转换器的旧代码库。完成这项工作有一个严格而严格的时间表,我认为现在转换到撒克逊会带来太大的变化和风险。

2 个答案:

答案 0 :(得分:0)

如果你正在做你说你正在做的事情并得到你说你得到的输出,那么它只能是XSLT处理器中的一个错误。

答案 1 :(得分:0)

正如一些人所指出的那样,你得到的结果毫无意义,但你的flattenText模板是非常不必要的。你可以替换它:

<xsl:call-template name="flattenText">
     <xsl:with-param name="node" select="current()"></xsl:with-param>
</xsl:call-template>

用这个:

<!-- Will work the same as flattenText current node is an element -->
<xsl:value-of select="." />

并删除flattenText模板。也许这会消除你的问题。