Access attribute from within current-grouping-key() xslt



I have some xml with thousands of movie elements which can all have 1 or MORE director and writer elements, if a director or writer has the same name as another, as seen here, I add an @differentiator of birthyear, if they are NOT the same person



<mediaList>
<movie id="1603934" dateCreated="2014-08-11">
<title>Night at the Museum</title>
<director>Shawn Levy</director>
<LCSpecialTopics>Comedy</LCSpecialTopics>
<writer>Robert Ben Garant</writer>
<writer differentiator="1970">Thomas Lennon</writer>
<language>English</language>
<year>2006</year>
</movie>

<movie lastModified="2014-08-30" id="1123629" dateCreated="2014-08-04">
<title type="foreign" xml:lang="cmn">Qiúgǎng Wèishì</title>
<title>Warriors of Qiugang</title>
<director>Ruby Yang</director>
<LCSpecialTopics>Documentary films</LCSpecialTopics>
<writer differentiator="1951">Thomas Lennon</writer>
<language>Chinese</language>
<year>2010</year>
</movie>
</mediaList>


my current XSLT to transform this into a nice readable table of



<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://ift.tt/tCZ8VR"
xmlns:xs="http://ift.tt/tphNwY" xmlns:functx="http://www.functx.com" version="2.0">
<xsl:output method="html" indent="yes"/>

<xsl:function name="functx:substring-after-last-match" as="xs:string"
xmlns:functx="http://www.functx.com">
<xsl:param name="arg" as="xs:string?"/>
<xsl:param name="regex" as="xs:string"/>

<xsl:sequence select="
replace($arg,concat('^.*',$regex),'')
"/>

</xsl:function>

<xsl:template match="mediaList">
<html>
<head>
<link rel="stylesheet" type="text/css" href="CssJs/tableMedia.css"/>
<title>Media Table</title>
</head>
<body>
<table>
<thead>
<tr>
<th>#</th>
<th>Person</th>
<th>Movies</th>
</tr>
</thead>
<tbody>
<xsl:for-each-group select="movie" group-by="writer | director">
<xsl:sort
select="functx:substring-after-last-match(current-grouping-key(),'\s')"/>
<xsl:sort select="current-grouping-key()"/>
<xsl:variable name="person" select="current-grouping-key()"/>

<tr>
<td>
<xsl:value-of select="position()"/>
</td>
<td>
<p>
<a id="{current-grouping-key()}">
<xsl:value-of select="$person"/>
</a>
</p>
</td>
<td>
<xsl:if test="current-group()[writer = $person]">
<h3>Writer</h3>
</xsl:if>
<xsl:apply-templates
select="current-group()[writer = $person]/title[not(@type)]"/>
<xsl:if test="current-group()[director = $person]">
<h3>Director</h3>
</xsl:if>
<xsl:apply-templates
select="current-group()[director = $person]/title[not(@type)]"
/>
</td>
</tr>
</xsl:for-each-group>
</tbody>
</table>
</body>
</html>
</xsl:template>

<xsl:template match="title">
<p>
<xsl:value-of select="."/>
<xsl:apply-templates select="../title[@type]"/>
</p>
</xsl:template>

<xsl:template match="title[@type]">
<span>
<xsl:value-of select="concat(' (',.,')')"/>
</span>
</xsl:template>
</xsl:stylesheet>


The problem is that I can't access the @differentiator after the group-by, I receive an error of "Required item type of first operand of '/' is node(); supplied value has item type xs:anyAtomicType. The expression can succeed only if the supplied value is an empty sequence."


from reading similar problems, i think there must be a way to perform this IN the group-by using concat() but because each movie element may have MORE than 1 writer/director I can't simply do



group-bye="concat(writer[@differentiator], writer/@differentiator) | writer | director">


desired output (snippet)would look like:



<tr>
<td>Some Number</td>
<td>
<p><a id="Thomas Lennon1951">Thomas Lennon (1951)</a></p>
</td>
<td>
<h3>Writer</h3>
<p>Warriors of Qiugang<span> (Qiúgǎng Wèishì)</span></p>
</td>
</tr>
<tr>
<td>Some Number</td>
<td>
<p><a id="Thomas Lennon1970">Thomas Lennon (1970)</a></p>
</td>
<td>
<h3>Writer</h3>
<p>Night at the Museum</p>
</td>
</tr>

No comments:

Post a Comment