I’ve a XML structure like this:
<root>
<element>
<name>Foo</name>
<subelement>
<key>1.1</key>
<value>Lorem ipsum</value>
</subelement>
<subelement>
<key>1.2</key>
<value>Lorem ipsum dolor</value>
</subelement>
</element>
<element>
<name>Bar</name>
<subelement>
<key>7.3.4</key>
<value>Seven three four</value>
</subelement>
<subelement>
<key>7.3.8</key>
<value>Seven three eight</value>
</subelement>
<subelement>
<key>7.1</key>
<value>Seven one</value>
</subelement>
</element>
</root>
What I try to achieve is to remove all <subelement>s except the one with the “highest” key.
I can’t seem to find any way to compare the <key>s of the <subelements>s within a certain <element>.
The resulting XML would look like:
<root>
<element>
<name>Foo</name>
<subelement>
<key>1.2</key>
<value>Lorem ipsum dolor</value>
</subelement>
</element>
<element>
<name>Bar</name>
<subelement>
<key>7.3.8</key>
<value>Seven three eight</value>
</subelement>
</element>
</root>
Any hints are very welcome.
This XSLT 2.0 transformation works for any number of “key components” in a key and for any possible positive integer value of any key component:
When this transformation is applied on the following XML document (the provided one, extended to be made more interesting):
the wanted, correct result is produced:
Explanation:
At the core of this generic solution is the function
my:max()which given a non-empty sequence of “structured values” (a structured value is a sequence of positive integers, joined with the ‘.’ character), produces one (of the many possible) maximum value.This function is recursive. It does the following:
If all the passed values are identical, then the first of them is returned.
Else, finds the maximum value of the first components.
If only one of the values has a first component with the found maximum value, return this value.
Else, find the maximum (recursively) of the “tails” of all values that have the maximum first component.
Finally, join together the maximum first component with the maximum of the “tails”, found in the previous step — and return this value.