Re: [xsl] Find elements with same key and merge sub-elements

Subject: Re: [xsl] Find elements with same key and merge sub-elements
From: "Martin Honnen martin.honnen@xxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Tue, 26 Sep 2023 19:41:38 -0000
On 26.09.2023 21:34, Larry Hayashi lhtrees@xxxxxxxxx wrote:
Hi,

I have an xml file containing dictionary entries with their
meanings/senses. I'd like to find Entries that have 2 or more senses
that have the same gloss. Sometimes an entry will have more than one
sense but each sense will have its own unique gloss. For the entries
that have senses with identical glosses, I want to merge those senses
and their contents as shown below.

Input
<Root>
B  B  <Entry form="voiture">
B  B  B  B  <Sense num="1">
B  B  B  B  B  B  <Gloss>car</Gloss>
B  B  B  B  B  B  <Index>
B  B  B  B  B  B  B  B  <IndexItem>automobile</IndexItem>
B  B  B  B  B  B  B  B  <IndexItem>vehicle</IndexItem>
B  B  B  B  B  B  B  B  <IndexItem>car</IndexItem>
B  B  B  B  B  B  </Index>
B  B  B  B  </Sense>
B  B  B  B  <Sense num="2">
B  B  B  B  B  B  <Gloss>car</Gloss>
B  B  B  B  B  B  <Category>transportation</Category>
B  B  B  B  </Sense>
B  B  </Entry>
B  B  <Entry>
B  B  B  B  <!-- ...Etc.... -->
B  B  </Entry>
</Root>

Desired Output:
<Root>
B  B  <Entry form="voiture">
B  B  B  B  <Sense num="1">
B  B  B  B  B  B  <Gloss>car</Gloss>
B  B  B  B  B  B  <Index>
B  B  B  B  B  B  B  B  <IndexItem>automobile</IndexItem>
B  B  B  B  B  B  B  B  <IndexItem>vehicle</IndexItem>
B  B  B  B  B  B  B  B  <IndexItem>car</IndexItem>
B  B  B  B  B  B  </Index>
B  B  B  B  B  B  <Category>transportation</Category>
B  B  B  B  </Sense>
B  B  </Entry>
B  B  <Entry>
B  B  B  B  <!-- ...Etc.... -->
B  B  </Entry>
</Root>

Thanks in advance for any pointers as to what might be the most
efficient approach.


It looks like a grouping problem so in XSLT 3 you can do something like the following (it is not quite clear whether common elements of a group of Entry elements with the same Gloss need to simply copied or also somehow merged)


<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"; B B B xmlns:xs="http://www.w3.org/2001/XMLSchema"; B B B exclude-result-prefixes="#all" B B B version="3.0">

B <xsl:mode on-no-match="shallow-copy"/>

B <xsl:output method="xml" indent="yes"/>

B  <xsl:template match="Entry">
B B B  <xsl:copy>
B B B B B  <xsl:apply-templates select="@*"/>
B B B B B  <xsl:for-each-group select="Sense" group-by="Gloss">
B B B B B B B  <xsl:copy>
B B B B B B B B B  <xsl:apply-templates select="@*, Gloss,
current-group()/(*
except Gloss)"/>
B B B B B B B  </xsl:copy>
B B B B B  </xsl:for-each-group>
B B B  </xsl:copy>
B  </xsl:template>

</xsl:stylesheet>

Current Thread