我有以下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
及其子节点,但它没有被调用,但文本直接被打印出来。
请让我知道我哪里出错了以及如何解决。
答案 0 :(得分:3)
好问题(感谢您提供完整,有效的示例!)。通常,如果元素不匹配,原因在于缺少名称空间:
您的输入XML中包含以下内容:
<texto xmlns="http://www.aranzadi.es/namespace/contenido/biblos/texto" idioma="spa">
换句话说,texto
元素位于命名空间中。在您的XSLT中,您有以下内容:
<xsl:template match="texto">
由于没有为包含xpath-default-namespace
或xsl: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中,因此仅在匹配或选择元素时需要此解决方案(给定您的示例输入)
此外,重要的是要认识到前缀无关紧要,它们不需要匹配源文档的前缀(或不存在)。重要的是,绑定到前缀的名称空间是匹配的。
如果存在子元素,在这种情况下为parrafo
和en-origen
,则这些元素将继承其父元素上给出的命名空间。因此,如果您还想匹配这些元素,则应在模式和XPath表达式中将其名称调整为tto:paraffo
和tto:en-origin
。