声明为匹配元素的模板,但从未触发
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:template
或 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">
现在您的模板将被匹配。
请记住,如果在该元素上声明了名称空间,则元素名称可以在名称空间中,但属性(除非前缀)不在名称空间中,因此仅在匹配或时才需要(给定示例输入)此解决方案选择元素。
此外,重要的是要认识到前缀并不重要,它们不需要与源文档中的前缀(或不存在前缀)相匹配。重要的是绑定到前缀的命名空间匹配。
如果有子元素,在本例中为 parrafo
和 en-origen
,它们将继承其父元素上给定的命名空间。所以如果你也想匹配这些元素,你应该在模式和XPath表达式中将它们的名称调整为tto:paraffo
和tto:en-origin
。
我有以下 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:template
或 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">
现在您的模板将被匹配。
请记住,如果在该元素上声明了名称空间,则元素名称可以在名称空间中,但属性(除非前缀)不在名称空间中,因此仅在匹配或时才需要(给定示例输入)此解决方案选择元素。
此外,重要的是要认识到前缀并不重要,它们不需要与源文档中的前缀(或不存在前缀)相匹配。重要的是绑定到前缀的命名空间匹配。
如果有子元素,在本例中为 parrafo
和 en-origen
,它们将继承其父元素上给定的命名空间。所以如果你也想匹配这些元素,你应该在模式和XPath表达式中将它们的名称调整为tto:paraffo
和tto:en-origin
。