声明为匹配元素的模板,但从未触发

Template declared to match element, but never triggered

我有以下 XML。

<?xml version="1.0" encoding="UTF-8"?>
<docs>
    <biblos>
        <texto xmlns="http://www.aranzadi.es/namespace/contenido/biblos/texto" idioma="spa">
            <parrafo>
                <en-origen estilo-fuente="cursiva">This is cursive text.</en-origen>
            </parrafo>
        </texto>
    </biblos>
</docs>

和以下 XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:output method="html" doctype-public="XSLT-compat" omit-xml-declaration="yes" encoding="UTF-8" indent="yes"/>
    <xsl:template match="/">
        <html>
            <body>
                <section class="chapter">
                    <xsl:apply-templates select="docs"/>
                </section>
            </body>
        </html>
    </xsl:template>
    <xsl:template match="docs">
        <div class="chapter">
        <xsl:text>Docs Block</xsl:text>
            <xsl:apply-templates select="biblos"/>
        </div>
    </xsl:template>
    <xsl:template match="biblos">
      <xsl:text>biblos block</xsl:text>
        <xsl:apply-templates/>
    </xsl:template>
    <xsl:template match="texto">
        <xsl:text>Text To Block</xsl:text>
        <xsl:apply-templates/>
    </xsl:template>
    <xsl:template match="parrafo">
        <div class="para">
            <xsl:apply-templates/>
        </div>
    </xsl:template>
    <xsl:template match="parrafo">
        <span class="format-smallcaps">
            <xsl:apply-templates/>
        </span>
    </xsl:template>
    <xsl:template match="en-origen">
        <xsl:variable name="fontStyle">
            <xsl:choose>
                <xsl:when test="./@estilo-fuente">
                    <xsl:value-of select="concat('font-style-',@estilo-fuente)"/>
                </xsl:when>
                <xsl:when test="./@format">
                    <xsl:value-of select="concat('format-',@format)"/>
                </xsl:when>
            </xsl:choose>
        </xsl:variable>
        <span class="{$fontStyle}">
            <xsl:value-of select="."/>
            <xsl:apply-templates select="para"/>
        </span>
    </xsl:template>
</xsl:transform>

当我 运行 这样做时,我得到以下输出。

<!DOCTYPE html
  PUBLIC "XSLT-compat">
<html>
   <body>
      <section class="chapter">
         <div class="chapter">Docs Blockbiblos block


                            This is cursive text.
         </div>
      </section>
   </body>
</html>

这里的问题是,虽然我已经在我的 XSLT 中声明了 texto 及其子节点,但它没有被调用,而是直接打印了文本。

请让我知道哪里出错了,我该如何解决。

问得好(感谢您提供完整、有效的示例!)。通常,如果元素不匹配,原因在于缺少命名空间:

您的输入内容如下 XML:

 <texto xmlns="http://www.aranzadi.es/namespace/contenido/biblos/texto" idioma="spa">

换句话说,texto 元素在命名空间中。在您的 XSLT 中,您有以下内容:

<xsl:template match="texto">

因为没有为 XPath 声明命名空间(xpath-default-namespace 在包含 xsl:templatexsl:stylesheet 上),这将在没有命名空间的元素 texto 上操作,这意味着,如所写,它将与您的来源中的 texto 不匹配。

您可以通过以下方式解决此问题:

<xsl:transform 
    xmlns:tto="http://www.aranzadi.es/namespace/contenido/biblos/texto"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">

和:

<xsl:template match="tto:texto">

现在您的模板将被匹配。

请记住,如果在该元素上声明了名称空间,则元素名称可以在名称空间中,但属性(除非前缀)不在名称空间中,因此仅在匹配或时才需要(给定示例输入)此解决方案选择元素。

此外,重要的是要认识到前缀并不重要,它们不需要与源文档中的前缀(或不存在前缀)相匹配。重要的是绑定到前缀的命名空间匹配。

如果有子元素,在本例中为 parrafoen-origen,它们将继承其父元素上给定的命名空间。所以如果你也想匹配这些元素,你应该在模式和XPath表达式中将它们的名称调整为tto:paraffotto:en-origin