I’m trying to figure out how XSLT process namespace prefixes and have following example:
XML:
<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"
xmlns:xhtml="http://www.w3.org/1999/xhtml"
xmlns:zno="http://feed.zinio.com/atom"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.w3.org/2005/Atom
http://www.w3.org/1999/xhtml
http://www.w3.org/2002/08/xhtml/xhtml1-strict.xsd
http://feed.zinio.com/atom" >
<entry>
<author>
<name>By Sheila F. Buckmaster</name>
</author>
<category xml:lang="en" term="TRAVEL"/>
<content>
<h2 class="hl2">One of the world’s most entrancing cities becomes even more captivating when costumed revelers fill its tiny streets and grand piazzas during Carnevale. It is here that a star of the silent screen comes alive, antics and all</h2>
<div class="byline">By Sheila F. Buckmaster</div>
</content>
</entry>
</feed>
XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xslt:stylesheet version="1.0" xmlns:xslt="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:user="urn:my-scripts"
xmlns:x="http://www.w3.org/1999/xhtml"
xmlns:AP="http://www.w3.org/2005/Atom"
exclude-result-prefixes="xslt msxsl user">
<xslt:output method="xml" indent="yes"/>
<xslt:template match="/">
<xslt:apply-templates select="/AP:feed//AP:entry"/>
</xslt:template>
<xslt:template match="AP:entry">
<xslt:text>Hello from entry</xslt:text>
<xslt:apply-templates select="AP:content"/>
</xslt:template>
<xslt:template match="AP:content">
<xslt:text>Hello from content</xslt:text>
<xslt:apply-templates select="x:div[@class='byline']"/>
</xslt:template>
<xslt:template match="x:div[@class='byline']">
<xslt:copy-of select="."/>
</xslt:template>
</xslt:stylesheet>
What I’m trying to do is to get access to my “div”. “Entry” and “Content” templates work fine since I specified namespace explicitly. But when I’m trying to get access to “div” using XHTML prefix (“x” in my case) – XSLT does not see it. It works only when I prefix “div” element with “AP” namespace:
<xslt:template match="AP:content">
<xslt:text>Hello from content</xslt:text>
<xslt:apply-templates select="AP:div[@class='byline']"/>
</xslt:template>
<xslt:template match="AP:div[@class='byline']">
<xslt:copy-of select="."/>
</xslt:template>
But this doesn’t look right to me because DIV element should be in XHTML namespace. What am I doing wrong here?
The Atom feed has the Atom namespace declared on the root element without a namespace prefix. The
<div/>and other XHTML elements are inheriting the Atom namespace because they do not have the XHTML namespace explicitly declared.If you want the XHTML elements to be bound to the XHTML namespace then you would need to change the
<div>in the Atom feed to be:or:
If you keep the Atom feed the same and still want to generate XHTML elements, then you will need to adjust your stylesheet to match on
AP:divand then construct XHTML elements in the output.For example, modifying your stylesheet I
apply-templateson the matchedAP:divin a mode namedxhtml. There is a template matching on any element in that mode (so it would also work for theAP:h2) that constructs XHTML elements using thelocal-name()of the matched element.