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

时间:2015-09-02 14:31:15

标签: xslt xslt-2.0

我有以下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及其子节点,但它没有被调用,但文本直接被打印出来。

请让我知道我哪里出错了以及如何解决。

1 个答案:

答案 0 :(得分:3)

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

您的输入XML中包含以下内容:

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

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

<xsl:template match="texto">

由于没有为包含xpath-default-namespacexsl:template的XPath(xsl: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">

现在您的模板将匹配。

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

此外,重要的是要认识到前缀无关紧要,它们不需要匹配源文档的前缀(或不存在)。重要的是,绑定到前缀的名称空间是匹配的。

如果存在子元素,在这种情况下为parrafoen-origen,则这些元素将继承其父元素上给出的命名空间。因此,如果您还想匹配这些元素,则应在模式和XPath表达式中将其名称调整为tto:paraffotto:en-origin