DanielShillock Posted December 7, 2011 Share Posted December 7, 2011 I am looking to display a list of document authors which reside in authors.xml depending on criteria on the document being viewed (for example, definitions.xml) Being new to XML/XSLT I gave it a shot, but nothing is displayed. <xsl:choose> <xsl:when test="$authors[doc='{@id}']"> <table> <xsl:for-each select="$authors"> <tr> <td><xsl:value-of select="$authors/author/name"/></td> <td><xsl:value-of select="$authors/author/email"/></td> <td><xsl:value-of select="$authors/author/@company"/></td> </tr> </xsl:for-each> </table></xsl:when></xsl:choose> To reiterate, when viewing definitions.xml I want to lookup authors.xml and display all the authors in a table which match the document being viewed. Examples below of definitions.xml and authors.xml defintions.xml <document xmlns:xhtml="http://www.w3.org/1999/xhtml"> <data id="definitions" status="Complete"> <p> This is an example of a page generated from XML. </p> </data></document> authors.xml <document> <data> <author doc="definitions" company="Airbus"> <name>Daniel Shillcock</name> <email>daniel.shillcock@example.com</email> </author <data><document> Link to comment Share on other sites More sharing options...
Martin Honnen Posted December 7, 2011 Share Posted December 7, 2011 You might want <xsl:when test="$authors[doc = current()/@id]"> instead of <xsl:when test="$authors[doc='{@id}']"> I would however use a key as follows: <xsl:variable name="authors" select="document('authors.xml')"/> <xsl:key name="k1" match="author" use="@doc"/> <xsl:template match="data"> <xsl:variable name="id" select="@id"/> <!-- for XSLT 1.0 need to change context document with for-each with XSLT 2.0 could simply use key('k1', $id, $authors) --> <xsl:for-each select="$authors"> <xsl:variable name="referenced-authors" select="key('k1', $id)"/> <xsl:if test="$referenced-authors"> <table> <xsl:apply-templates select="$referenced-authors"/> </table> </xsl:if> </xsl:for-each></xsl:template> <xsl:template match="author"> <tr> <xsl:apply-templates select="*"/> <xsl:apply-templates select="@company"/> </tr></xsl:template> <xsl:template match="author/* | author/@company"> <td> <xsl:value-of select="."/> </td></xsl:template> Link to comment Share on other sites More sharing options...
DanielShillock Posted December 7, 2011 Author Share Posted December 7, 2011 Thank you for your quick response! This seems to work brilliantly. The only issue I have now is that whever I place this in my XSLT it only displays this content and doesn't appear to display any other templates found. I imagine I am overlooking something blindingly obvious. Link to comment Share on other sites More sharing options...
DanielShillock Posted December 7, 2011 Author Share Posted December 7, 2011 As I suspected, it is calling from both documents and displaying whatever is called last. Link to comment Share on other sites More sharing options...
Martin Honnen Posted December 7, 2011 Share Posted December 7, 2011 Sorry but it is hard to tell why something fails in a larger context if that larger context is not presented.To put my suggested code into a complete stylesheet outputting an HTML document for the definitions.xml as its input I wrote the sample http://home.arcor.de/martin.honnen/xslt/test2011120701.xml. The stylesheet is http://home.arcor.de/martin.honnen/xslt/test2011120701.xsl.If that does not help then you will need to show us more of your code, the output you want and the one you get. Link to comment Share on other sites More sharing options...
DanielShillock Posted December 8, 2011 Author Share Posted December 8, 2011 Thank you for the response. Here is a cutdown version of the XSLT. I can't figure out where to place the code you kindly gave me, where ever I place it results in either a page not being displayed properly (ie, nothing at all) or just the authors table being displayed. Apologises for the indentation! <?xml version="1.0" encoding="utf-8"?><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xhtml="http://www.w3.org/1999/xhtml"><xsl:variable name="authors" select="document('authors.xml')"/><xsl:key name="k1" match="author" use="@doc"/> <!-- Doctype - about:legacy-compat is XML equivalent of HTML5 doctype --> <xsl:output method="html" indent="yes" omit-xml-declaration="yes" doctype-public="about:legacy-compat" /> <xsl:template match="document"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" > <head> <title>Documentation</title> </head> <body> <xsl:apply-templates/> </body> </html> </xsl:template> <!-- This section will lookup HTML tags within the XML document forward to HTML as tag --> <xsl:template match="p"> <xsl:copy> <xsl:apply-templates/> </xsl:copy> </xsl:template> <!-- End of HTML tag lookup --> <xsl:template match="data"> <div class="content"> <xsl:apply-templates/> </div> </xsl:template> <xsl:template match="note"> <div class="note"> <xsl:apply-templates/> </div> </xsl:template> <xsl:template match="image"> <div class="image"> <a title="{.}" rel="lightbox" href="images/{@name}_large.jpg"><img title="{@name}" src="images/{@name}_thumb.jpg"/></a> <div> <xsl:value-of select="@name"/> </div> </div> </xsl:template> <xsl:template name="authors" match="data"> <xsl:variable name="id" select="@id"/> <!-- for XSLT 1.0 need to change context document with for-each with XSLT 2.0 could simply use key('k1', $id, $authors) --> <xsl:for-each select="$authors"> <xsl:variable name="referenced-authors" select="key('k1', $id)"/> <xsl:if test="$referenced-authors"> <table> <xsl:apply-templates select="$referenced-authors"/> </table> </xsl:if> </xsl:for-each> </xsl:template> <xsl:template match="author"> <tr> <xsl:apply-templates select="*"/> <xsl:apply-templates select="@company"/> </tr> </xsl:template> <xsl:template match="author/* | author/@company"> <td> <xsl:value-of select="."/> </td> </xsl:template></xsl:stylesheet> Link to comment Share on other sites More sharing options...
Martin Honnen Posted December 8, 2011 Share Posted December 8, 2011 Your latest stylesheet contains two competing templates with match="data", in that case the XSLT processor can either report an error or choose the last such template.You haven't told us which output you want but I suspect you want to add an xsl:apply-templates inside of the template with match="data". I already did that however in the sample http://home.arcor.de/martin.honnen/xslt/test2011120701.xsl so I am not sure why you did not follow up on that example. Link to comment Share on other sites More sharing options...
DanielShillock Posted December 8, 2011 Author Share Posted December 8, 2011 Aaah, thank you very much. I'm not sure why I didn't include it! I must have missed it. Your help has been greatly appreciated! Link to comment Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.