XSLT Grouping in subgroups using the generate-id () function discards duplicate keys from previous groups

I'm having problems creating collapsed groups when the keys I need can be repeated in different groups from my input file. I am using the muenchian method to group, as I am stuck in xslt 1.0 and I cannot change the input scheme.

<groups> <group id="1"> <members> <member name="A"> <udf @name="key">1</customId> </member> <member name="B"> <udf @name="key">1</customId> </member> </members> </group> <group id="2"> <members> <member name="C"> <udf @name="key">1</customId> </member> <member name="D"> <udf @name="key">2</customId> </member> <member name="E"> <udf @name="key">3</customId> </member> </members> </group> </groups> 

The output I want to create is:

 <group id="1"> <member key="1" /> </group> <group id="2"> <member key="1" /> <member key="2" /> <member key="3" /> </group> 

I also do a different processing for each element, but this is tangential.

I have a template that starts a loop and generates a key:

 <xsl:tempalte name="process"> <xsl:for-each select="groups/group"> <xsl:call-template name="getMembers"/> </xsl:for-each> </xsl:tempalte> <xsl:key name="keyId" match="member" use="udf/@name[.='key']/.."/> <xsl:template name="getMembers> <xsl:for-each select="members/member[generate-id() = generate-id(key('keyId',udf/@name[.='key']/..))]"> <!-- emits the grouped tags. --> </xsl:for-each> </xsl:template> 

So far, what I get with this conversion:

 <group id="1"> <member key="1" /> </group> <group id="2"> <member key="2" /> <member key="3" /> </group> 

.. you will see its missing key 1 from group 2. So, I am confused by the fact that the second time the template is called, the generation identifier function does not emit a new unique key for the value “1”, although I call to generate id in the context which I thought of group 2.

+4
source share
1 answer

You need to use a concatenated key that accepts the parent element of group or members , for example.

 <xsl:key name="keyId" match="member" use="concat(generate-id(parent::members/parent::group), '|', udf[@name = 'key'])"/> 

then, of course, anywhere, where you use the key function necessary for you to calculate it with the same expression, for example.

 <xsl:for-each select="members/member[generate-id() = generate-id(key('keyId', concat(generate-id(parent::members/parent::group), '|', udf[@name = 'key'])))]"> 
+5
source

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


All Articles