xml - Treating sibling nodes as one for XSLT Muenchian grouping -


i'm trying use muenchian grouping display company policy documents in hierarchical way. policy documents added sharepoint , tagged language, category , document type. i'm using xml creates.

i need take data 2 merged lists. way sharepoint works, my xml looks (with rows element each sharepoint list): i've had simplify remove hundreds of attributes sp adds went on stackoverflowsize limit, structure accurate.

<dsqueryresponse>   <rows>     <row title="testitem" category="category 1" language="english" documenttype="content" />   </rows>   <rows>     <row title="doc1" category="category 1" language="english" documenttype="policy" />     <row title="policy2" category="category 2" language="english" documenttype="policy" />     <row title="policy3" category="category 1" language="nederlands (dutch)" documenttype="form" />   </rows> </dsqueryresponse> 

current xsl looks this:

<xsl:stylesheet    version="1.0"    xmlns:xsl="http://www.w3.org/1999/xsl/transform"   xmlns:sharepoint="microsoft.sharepoint.webcontrols"   xmlns:__designer="http://schemas.microsoft.com/webparts/v2/dataview/designer"   xmlns:agg="http://schemas.microsoft.com/sharepoint/aggregatesource"   xmlns:asp="http://schemas.microsoft.com/aspnet/20"   xmlns:d="http://schemas.microsoft.com/sharepoint/dsp"   xmlns:ddwrt="http://schemas.microsoft.com/webparts/v2/dataview/runtime"   xmlns:ddwrt2="urn:frontpage:internal"   xmlns:msxsl="urn:schemas-microsoft-com:xslt"   xmlns:x="http://www.w3.org/2001/xmlschema"   xmlns:xs="http://www.w3.org/2001/xmlschema"   exclude-result-prefixes="xsl msxsl ddwrt"    ddwrt:oob="true" >   <xsl:output indent="yes" omit-xml-declaration="yes" />   <xsl:key name="bylanguage" match="/dsqueryresponse/rows/row" use="@language" />   <xsl:key name="bycategory" match="/dsqueryresponse/rows/row" use="concat(@language, '+', @category)" />    <xsl:template match="/">     <xsl:apply-templates select="/dsqueryresponse/rows/row[count(. | key('bylanguage', @language)[1]) = 1]/@language">       <xsl:sort select="." order="ascending" />     </xsl:apply-templates>   </xsl:template>    <xsl:template match="@language">     <br /><b>below can see policies in <xsl:value-of select="." /></b><br /><br />     <xsl:variable name="thislanguage" select="key('bylanguage', .)" />     <xsl:apply-templates select="$thislanguage[count(. | key('bycategory', concat(@language, '+', @category))[1])= 1]/@category">       <xsl:sort select="." order="ascending" />     </xsl:apply-templates>   </xsl:template>    <xsl:template match="@category">     <br />category: <xsl:value-of select="." />     <xsl:apply-templates select="key('bycategory', concat(../@language, '+', .))" />   </xsl:template>    <xsl:template match="/dsqueryresponse/rows/row">     <br />title: <xsl:value-of select="@title" />   </xsl:template> </xsl:stylesheet> 

and current result looks (a mess):

 below can see policies in english   category: category 1 title: testitem  category: category 2 title: policy2  below can see policies in english  category: category 1 title: testitem  category: category 2 title: policy2  below can see policies in nederlands (dutch)  category: category 1 title: policy3   **my desired output is:**  below can see policies in english   category: category 1 title: testitem title: doc1  category: category 2 title: policy2  below can see policies in nederlands (dutch)  category: category 1 title: policy3  

so seem getting lots of duplication, presumably because getting called twice, once each of rows elements? i'm novice xsl appreciated.

========== update ==========

the code below works me in sharepoint (the bulky looking choose statements aren't technically necessary needed them rid of non-english characters jquery i've put on top of this):

full xslt:

<xsl:stylesheet xmlns:xs="http://www.w3.org/2001/xmlschema" xmlns:x="http://www.w3.org/2001/xmlschema" xmlns:d="http://schemas.microsoft.com/sharepoint/dsp" xmlns:agg="http://schemas.microsoft.com/sharepoint/aggregatesource" version="1.0" exclude-result-prefixes="xsl msxsl ddwrt" xmlns:ddwrt="http://schemas.microsoft.com/webparts/v2/dataview/runtime" xmlns:asp="http://schemas.microsoft.com/aspnet/20" xmlns:__designer="http://schemas.microsoft.com/webparts/v2/dataview/designer" xmlns:xsl="http://www.w3.org/1999/xsl/transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:sharepoint="microsoft.sharepoint.webcontrols" xmlns:ddwrt2="urn:frontpage:internal" ddwrt:oob="true">  <xsl:output indent="yes" omit-xml-declaration="yes"/> <xsl:key name="bylanguage" match="/dsqueryresponse/rows/row" use="@language" /> <xsl:key name="bycategory" match="/dsqueryresponse/rows/row" use="concat(@language, '+', @category)" />  <xsl:template match="/"> <div id="tabs" style="display:none;"> <!--create tabs--> <ul> <xsl:apply-templates select="/dsqueryresponse/rows/row[count(. | key('bylanguage', @language)[2]) = 1]/@language"> <xsl:sort select="." order="ascending" /> </xsl:apply-templates> </ul> <!--create content--> <xsl:apply-templates select="/dsqueryresponse/rows/row[count(. | key('bylanguage', @language)[2]) = 1]/@language" mode="pass2"> <xsl:sort select="." order="ascending" /> </xsl:apply-templates> </div> </xsl:template>  <!--do first pass create tabs --> <xsl:template match="@language"> <li> <xsl:choose> <xsl:when test=". = 'english'"><xsl:text disable-output-escaping="yes">&lt;a href="#english"&gt;</xsl:text><xsl:value-of select="." /><xsl:text disable-output-escaping="yes">&lt;/a&gt;</xsl:text></xsl:when> <xsl:when test=". = 'bahasa'"><xsl:text disable-output-escaping="yes">&lt;a href="#bahasa"&gt;</xsl:text><xsl:value-of select="." /><xsl:text disable-output-escaping="yes">&lt;/a&gt;</xsl:text></xsl:when> <xsl:when test=". = '简体中文 (chinese)'"><xsl:text disable-output-escaping="yes">&lt;a href="#chinese"&gt;</xsl:text><xsl:value-of select="." /><xsl:text disable-output-escaping="yes">&lt;/a&gt;</xsl:text></xsl:when> <xsl:when test=". = 'nederlands (dutch)'"><xsl:text disable-output-escaping="yes">&lt;a href="#dutch"&gt;</xsl:text><xsl:value-of select="." /><xsl:text disable-output-escaping="yes">&lt;/a&gt;</xsl:text></xsl:when> <xsl:when test=". = 'français (french)'"><xsl:text disable-output-escaping="yes">&lt;a href="#french"&gt;</xsl:text><xsl:value-of select="." /><xsl:text disable-output-escaping="yes">&lt;/a&gt;</xsl:text></xsl:when> <xsl:when test=". = 'deutsch (german)'"><xsl:text disable-output-escaping="yes">&lt;a href="#german"&gt;</xsl:text><xsl:value-of select="." /><xsl:text disable-output-escaping="yes">&lt;/a&gt;</xsl:text></xsl:when> <xsl:when test=". = 'italiano (italian)'"><xsl:text disable-output-escaping="yes">&lt;a href="#italian"&gt;</xsl:text><xsl:value-of select="." /><xsl:text disable-output-escaping="yes">&lt;/a&gt;</xsl:text></xsl:when> <xsl:when test=". = '日本語 (japanese)'"><xsl:text disable-output-escaping="yes">&lt;a href="#japanese"&gt;</xsl:text><xsl:value-of select="." /><xsl:text disable-output-escaping="yes">&lt;/a&gt;</xsl:text></xsl:when> <xsl:when test=". = '한국의 (korean)'"><xsl:text disable-output-escaping="yes">&lt;a href="#korean"&gt;</xsl:text><xsl:value-of select="." /><xsl:text disable-output-escaping="yes">&lt;/a&gt;</xsl:text></xsl:when> <xsl:when test=". = 'polski (polish)'"><xsl:text disable-output-escaping="yes">&lt;a href="#polish"&gt;</xsl:text><xsl:value-of select="." /><xsl:text disable-output-escaping="yes">&lt;/a&gt;</xsl:text></xsl:when> <xsl:when test=". = 'português (portuguese)'"><xsl:text disable-output-escaping="yes">&lt;a href="#portuguese"&gt;</xsl:text><xsl:value-of select="." /><xsl:text disable-output-escaping="yes">&lt;/a&gt;</xsl:text></xsl:when> <xsl:when test=". = 'pyccĸИЙ (russian)'"><xsl:text disable-output-escaping="yes">&lt;a href="#russian"&gt;</xsl:text><xsl:value-of select="." /><xsl:text disable-output-escaping="yes">&lt;/a&gt;</xsl:text></xsl:when> <xsl:when test=". = 'castellano (spanish)'"><xsl:text disable-output-escaping="yes">&lt;a href="#spanish"&gt;</xsl:text><xsl:value-of select="." /><xsl:text disable-output-escaping="yes">&lt;/a&gt;</xsl:text></xsl:when> </xsl:choose> </li> </xsl:template>  <!--and second pass else--> <xsl:template match="@language" mode="pass2"> <xsl:choose> <xsl:when test=". = 'english'"><xsl:text disable-output-escaping="yes">&lt;div id="english"&gt;</xsl:text></xsl:when> <xsl:when test=". = 'bahasa'"><xsl:text disable-output-escaping="yes">&lt;div id="bahasa"&gt;</xsl:text></xsl:when> <xsl:when test=". = '简体中文 (chinese)'"><xsl:text disable-output-escaping="yes">&lt;div id="chinese"&gt;</xsl:text></xsl:when> <xsl:when test=". = 'nederlands (dutch)'"><xsl:text disable-output-escaping="yes">&lt;div id="dutch"&gt;</xsl:text></xsl:when> <xsl:when test=". = 'français (french)'"><xsl:text disable-output-escaping="yes">&lt;div id="french"&gt;</xsl:text></xsl:when> <xsl:when test=". = 'deutsch (german)'"><xsl:text disable-output-escaping="yes">&lt;div id="german"&gt;</xsl:text></xsl:when> <xsl:when test=". = 'italiano (italian)'"><xsl:text disable-output-escaping="yes">&lt;div id="italian"&gt;</xsl:text></xsl:when> <xsl:when test=". = '日本語 (japanese)'"><xsl:text disable-output-escaping="yes">&lt;div id="japanese"&gt;</xsl:text></xsl:when> <xsl:when test=". = '한국의 (korean)'"><xsl:text disable-output-escaping="yes">&lt;div id="korean"&gt;</xsl:text></xsl:when> <xsl:when test=". = 'polski (polish)'"><xsl:text disable-output-escaping="yes">&lt;div id="polish"&gt;</xsl:text></xsl:when> <xsl:when test=". = 'português (portuguese)'"><xsl:text disable-output-escaping="yes">&lt;div id="portuguese"&gt;</xsl:text></xsl:when> <xsl:when test=". = 'pyccĸИЙ (russian)'"><xsl:text disable-output-escaping="yes">&lt;div id="russian"&gt;</xsl:text></xsl:when> <xsl:when test=". = 'castellano (spanish)'"><xsl:text disable-output-escaping="yes">&lt;div id="spanish"&gt;</xsl:text></xsl:when> </xsl:choose> <b>below can see policies in <xsl:value-of select="." /></b><br /><br/>  <div class="accordion"> <xsl:variable name="thislanguage" select="key('bylanguage', .)" /> <xsl:apply-templates select="$thislanguage[count(. | key('bycategory', concat(@language, '+', @category))[2])= 1]/@category"> <xsl:sort select="." order="ascending" /> </xsl:apply-templates> </div>  <xsl:text disable-output-escaping="yes">&lt;/div&gt;</xsl:text> </xsl:template>  <xsl:template match="@category"> <h3> <xsl:value-of select="." /> </h3>  <div class="accordioncontent"> <xsl:apply-templates select="key('bycategory', concat(../@language, '+', .))"/> </div> </xsl:template>  <xsl:template match="/dsqueryresponse/rows/row"> <div class="policy-item"> <div class="policy-item-title"> <xsl:value-of select="@title" /> </div> <xsl:if test="@itemhtml != ''"> <div class="policy-item-content"> <xsl:value-of select="@itemhtml" disable-output-escaping="yes" /> </div> </xsl:if> </div> </xsl:template>  </xsl:stylesheet> 

here do:

<xsl:stylesheet    version="1.0"    xmlns:xsl="http://www.w3.org/1999/xsl/transform"   xmlns:sharepoint="microsoft.sharepoint.webcontrols"   xmlns:__designer="http://schemas.microsoft.com/webparts/v2/dataview/designer"   xmlns:agg="http://schemas.microsoft.com/sharepoint/aggregatesource"   xmlns:asp="http://schemas.microsoft.com/aspnet/20"   xmlns:d="http://schemas.microsoft.com/sharepoint/dsp"   xmlns:ddwrt="http://schemas.microsoft.com/webparts/v2/dataview/runtime"   xmlns:ddwrt2="urn:frontpage:internal"   xmlns:msxsl="urn:schemas-microsoft-com:xslt"   xmlns:x="http://www.w3.org/2001/xmlschema"   xmlns:xs="http://www.w3.org/2001/xmlschema"   exclude-result-prefixes="msxsl ddwrt sharepoint __designer agg asp d ddwrt2 x"    ddwrt:oob="true" >   <xsl:output method="html" indent="yes" omit-xml-declaration="yes" />   <xsl:key name="krowbylanguage" match="row" use="@language" />   <xsl:key name="krowbycategory" match="row" use="concat(@language, '+', @category)" />    <xsl:template match="/">     <html>       <body>         <xsl:apply-templates select="dsqueryresponse/rows" />       </body>     </html>   </xsl:template>    <xsl:template match="rows">     <xsl:apply-templates mode="language" select="row[       count(. | key('krowbylanguage', @language)[1]) = 1     ]">       <xsl:sort select="@language" order="ascending" />     </xsl:apply-templates>   </xsl:template>    <xsl:template match="row" mode="language">     <xsl:variable name="mycategory" select="concat(@language, '+', @category)" />     <div class="language">       <div>         <xsl:text>below can see policies in </xsl:text>         <xsl:value-of select="@language" />       </div>       <div>         <xsl:apply-templates mode="category" select="key('krowbylanguage', @language)[             count(. | key('krowbycategory', $mycategory)[1]) = 1         ]">           <xsl:sort select="@category" order="ascending" />         </xsl:apply-templates>       </div>     </div>   </xsl:template>    <xsl:template match="row" mode="category">     <xsl:variable name="mycategory" select="concat(@language, '+', @category)" />     <div class="catecory">       <div>         <xsl:text>category: </xsl:text>         <xsl:value-of select="@category" />       </div>       <div>         <xsl:apply-templates mode="title" select="key('krowbycategory', $mycategory)" />       </div>     </div>   </xsl:template>    <xsl:template match="row" mode="title">     <div>       <xsl:text>title: </xsl:text>       <xsl:value-of select="@title" />     </div>   </xsl:template> </xsl:stylesheet> 

output (i recommend using css formatting output, instead of using <br>):

<html>    <body>       <div class="language">          <div>below can see policies in english</div>          <div>             <div class="catecory">                <div>category: category 1</div>                <div>                   <div>title: testitem</div>                   <div>title: doc1</div>                </div>             </div>          </div>       </div>       <div class="language">          <div>below can see policies in nederlands (dutch)</div>          <div>             <div class="catecory">                <div>category: category 1</div>                <div>                   <div>title: policy3</div>                </div>             </div>          </div>       </div>    </body> </html> 

the primary change move of subgroup key (language + category) variable $mycategory, enables selecting right nodes in double grouping.

your original expression:

$thislanguage[count(. | key('bycategory', concat(@language, '+', @category))[1])= 1] 

refers wrong context inside predicate (it refers $thislanguage, not have @language or @category). moving concat(...) out of expression generates correct results.

the secondary change adding structure output can targeted more via css.

also note output method , use of different template modes.

general hint: have many namespace declarations in stylesheet. remove don't actively use in stylesheet.


Comments

Popular posts from this blog

javascript - AngularJS custom datepicker directive -

javascript - jQuery date picker - Disable dates after the selection from the first date picker -