Reputation: 3351
I've the following 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>
and the following 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>
when i run this, I'm getting the below output.
<!DOCTYPE html
PUBLIC "XSLT-compat">
<html>
<body>
<section class="chapter">
<div class="chapter">Docs Blockbiblos block
This is cursive text.
</div>
</section>
</body>
</html>
Here the problem is, though I've declared texto
and child nodes of it in my XSLT, it is not getting called, but the text is directly getting printed.
Please let me know where I'm going wrong and how I can fix it.
Upvotes: 2
Views: 417
Reputation: 57217
Good question (thanks for providing a complete, working example!). Often, if elements are not matched, the cause lies in missing namespaces:
You have the following in your input XML:
<texto xmlns="http://www.aranzadi.es/namespace/contenido/biblos/texto" idioma="spa">
In other words, the texto
element is in a namespace. In your XSLT you have the following:
<xsl:template match="texto">
Since no namespace is declared for XPath (xpath-default-namespace
on the containing xsl:template
or xsl:stylesheet
), this will operate on elements texto
in no namespace, meaning, as written, it will not match texto
from your source.
You can solve this by:
<xsl:transform
xmlns:tto="http://www.aranzadi.es/namespace/contenido/biblos/texto"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
and:
<xsl:template match="tto:texto">
Now your template will be matched.
Remember that element names can be in a namespace if the namespace is declared on that element, but the attributes, unless prefixes, are in no nammespace, so this solution is only required (given your example input) on matching or selecting elements.
Also, it is important to realize that prefixes do not matter, they do not need to match the prefix (or absence thereof) from the source document. What matters, is that the namespace bound to the prefix matches.
If there are child elements, in this case parrafo
and en-origen
, these inherit the namespace given on their parent element. So if you want to match these elements as well, you should adjust their names to tto:paraffo
and tto:en-origin
in patterns and XPath expressions.
Upvotes: 4