XSLT and the default namespace for XHTML output

I am trying to understand how XSLT process namespace prefixes have the 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 access my "div". The Entry and Content templates work fine, as I explicitly specified the namespace. But when I try to access the "div" using the XHTML prefix ("x" in my case), XSLT does not see this. It only works when I prefix the div element with the 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 does not look right, because the DIV element must be in the XHTML namespace. What am I doing wrong here?

+4
source share
2 answers

The Atom feed has an Atom namespace specified in the root element without a namespace prefix. The <div/> and other XHTML elements inherit the Atom namespace because they did not explicitly declare the XHTML namespace.

If you want XHTML elements to be bound to the XHTML namespace, you will need to change the <div> in the Atom feed:

 <div xmlns:xhtml="http://www.w3.org/1999/xhtml" class="byline">By Sheila F. Buckmaster</div> 

or

 <xhtml:div class="byline">By Sheila F. Buckmaster</xhtml:div> 

If you keep the Atom feed the same and want to generate XHTML elements, you will need to tweak the stylesheet to match the AP:div , and then construct the XHTML elements in the output.

For example, by changing the stylesheet, I apply-templates on the matching AP:div in the mode named xhtml . There is pattern matching for any element in this mode (therefore it will also work for AP:h2 ), which builds XHTML elements using the local-name() matching element.

 <?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="AP:div[@class='byline']"/> </xslt:template> <xslt:template match="AP:div[@class='byline']"> <xslt:apply-templates select="." mode="xhtml"/> </xslt:template> <!--create an XHTML element with the same name as the context element --> <xslt:template match="*" mode="xhtml"> <xslt:element name="{local-name()}" namespace="http://www.w3.org/1999/xhtml"> <xslt:apply-templates select="@*|node()" mode="xhtml"/> </xslt:element> </xslt:template> <!--attributes, comments, and processing-instructions simply copied --> <xslt:template match="@*|text()|comment()|processing-instruction()"> <xslt:copy-of select="."/> </xslt:template> </xslt:stylesheet> 
+2
source

In your xml, your div should be xhtml: div

+2
source

Source: https://habr.com/ru/post/1402133/


All Articles