Another question about getting different values using XSLT 1.0. Here is a stupid, compiled example that should illustrate my problem.
<?xml version="1.0" encoding="UTF-8"?>
<moviesByYear>
<year1994>
<movie>
<genre>Action</genre>
<director>A</director>
</movie>
</year1994>
<year1994>
<movie>
<genre>Comedy</genre>
<director>A</director>
</movie>
</year1994>
<year1994>
<movie>
<genre>Drama</genre>
<director>B</director>
</movie>
</year1994>
<year1994>
<movie>
<genre>Thriller</genre>
<director>C</director>
</movie>
</year1994>
<year1995>
<movie>
<genre>Action</genre>
<director>A</director>
</movie>
</year1995>
<year1995>
<movie>
<genre>Comedy</genre>
<director>C</director>
</movie>
</year1995>
<year1996>
<movie>
<genre>Thriller</genre>
<director>A</director>
</movie>
</year1996>
</moviesByYear>
Now let me say that I would like to list all the years when films were created that are either comedies or director B. I use the following stylesheet:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:output method="text" encoding="UTF-8" indent="no"/>
<xsl:template match="/">
<xsl:for-each select="/moviesByYear/*[movie/genre='Comedy' or movie/director='B']">
<xsl:value-of select="name()"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
This gives me the following result:
year1994year1994year1995
I have not yet found a solution to get the various values that will work here. For example, an name(.) != name(following-sibling::*)exception is thrown when used year1994.
In my real case, I have a complex XML and XPath structure with many criteria that select multiple nodes from which I need to get the output of different node names.
: michael.hor257k , xsl:. :
<?xml version="1.0" encoding="UTF-8"?>
<root>
<genres>
<genre>Action</genre>
<genre>Comedy</genre>
<genre>Drama</genre>
<genre>Thriller</genre>
</genres>
<moviesByYear>
<year1994>
<movie>
<genre>Action</genre>
<director>A</director>
</movie>
</year1994>
<year1994>
<movie>
<genre>Comedy</genre>
<director>A</director>
</movie>
</year1994>
<year1994>
<movie>
<genre>Drama</genre>
<director>B</director>
</movie>
</year1994>
<year1994>
<movie>
<genre>Thriller</genre>
<director>C</director>
</movie>
</year1994>
<year1995>
<movie>
<genre>Action</genre>
<director>A</director>
</movie>
</year1995>
<year1995>
<movie>
<genre>Comedy</genre>
<director>C</director>
</movie>
</year1995>
<year1996>
<movie>
<genre>Thriller</genre>
<director>A</director>
</movie>
</year1996>
</moviesByYear>
</root>
, , , . :
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="urn:schemas-microsoft-com:xslt"
extension-element-prefixes="exsl">
<xsl:output method="text" version="1.0" encoding="UTF-8" indent="no"/>
<xsl:template match="/">
<xsl:for-each select="/root/genres/genre">
<xsl:call-template name="output">
<xsl:with-param name="genre">
<xsl:value-of select="."/>
</xsl:with-param>
</xsl:call-template>
</xsl:for-each>
</xsl:template>
<xsl:param name="director" select="'B'"/>
<xsl:key name="year" match="year" use="." />
<xsl:template name="output">
<xsl:param name="genre"/>
<xsl:variable name="years">
<xsl:for-each select="/root/moviesByYear/*/movie[genre=$genre or director=$director]">
<year><xsl:value-of select="local-name(..)"/></year>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="years-set" select="exsl:node-set($years)" />
<xsl:value-of select="concat($genre, ': ')"/>
<xsl:for-each select="$years-set/year[count(. | key('year', .)[1]) = 1]">
<xsl:value-of select="."/>
</xsl:for-each>
<xsl:text> </xsl:text>
</xsl:template>
</xsl:stylesheet>
:
Action: year1994year1995
Comedy:
Drama:
Thriller: year1996
, . :
Action: year1994year1995
Comedy: year1994year1995
Drama: year1994
Thriller: year1994year1996