Reputation: 25
Have the following input
<item>
<list>
<name>a</name>
<vaue>a1</vaue>
</list>
<list>
<name>b</name>
<vaue>b5</vaue>
</list>
<list>
<name>c</name>
<vaue>c9</vaue>
</list>
<list>
<name>d</name>
<vaue>d66</vaue>
</list>
<type>1</type>
</item>
<item>
<list>
<name>a</name>
<vaue>a1</vaue>
</list>
<list>
<name>b</name>
<vaue>b5</vaue>
</list>
<list>
<name>c</name>
<vaue>c9</vaue>
</list>
<list>
<name>d</name>
<vaue>d66</vaue>
</list>
<type>2</type>
</item>
<item>
<list>
<name>a</name>
<vaue>a1</vaue>
</list>
<list>
<name>b</name>
<vaue>b5</vaue>
</list>
<list>
<name>c</name>
<vaue>c9</vaue>
</list>
<list>
<name>d</name>
<vaue>d66</vaue>
</list>
<type>1</type>
</item>
<item>
<list>
<name>a</name>
<vaue>a1</vaue>
</list>
<list>
<name>b</name>
<vaue>b5</vaue>
</list>
<list>
<name>c</name>
<vaue>c9</vaue>
</list>
<list>
<name>d</name>
<vaue>d66</vaue>
</list>
<type>2</type>
</item>
Would now like to have the following output
<item>
<list>
<name>a</name>
<vaue>a1</vaue>
</list>
<list>
<name>b</name>
<vaue>b5</vaue>
</list>
<list>
<name>c</name>
<vaue>c9</vaue>
</list>
<list>
<name>d</name>
<vaue>d66</vaue>
</list>
<type>1</type>
</item>
<item>
<list>
<name>a</name>
<vaue>a1</vaue>
</list>
<list>
<name>b</name>
<vaue>b5</vaue>
</list>
<list>
<name>c</name>
<vaue>c9</vaue>
</list>
<list>
<name>d</name>
<vaue>d66</vaue>
</list>
<type>2</type>
</item>
<item>
<list>
<name>a</name>
<vaue>a9</vaue>
</list>
<list>
<name>b</name>
<vaue>b5</vaue>
</list>
<list>
<name>c</name>
<vaue>c9</vaue>
</list>
<list>
<name>d</name>
<vaue>d66</vaue>
</list>
<type>1</type>
</item>
<item>
<list>
<name>a</name>
<vaue>a1</vaue>
</list>
<list>
<name>b</name>
<vaue>b5</vaue>
</list>
<list>
<name>c</name>
<vaue>c9</vaue>
</list>
<list>
<name>d</name>
<vaue>d66</vaue>
</list>
<type>2</type>
</item>
<item>
<list>
<name>a</name>
<vaue>a1</vaue>
</list>
<type>3</type>
</item>
<item>
<list>
<name>a</name>
<vaue>a9</vaue>
</list>
<type>3</type>
</item>
For each item present with type as 1 would like to create a new item if there if the list contains a name which is "a" . However would like to avoid duplicates. Was able to achieve this output already with a two step process.. first to create items with duplicates and then a separate key match to remove the duplicates.
Is there a way we can achieve this in one step instead of to create duplicates and then filter duplicates
Upvotes: 0
Views: 36
Reputation: 1882
This is just a grouping problem. This stylesheet:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:key name="item-by-vaue" match="item[type=1]" use="list[name='a']/vaue"/>
<xsl:template match="node()|@*" name="copy">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="root">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
<xsl:for-each
select="item[type=1]
[count(.|key('item-by-vaue',list[name='a']/vaue)[1])=1]">
<item>
<xsl:apply-templates select="list[name='a']"/>
<type>3</type>
</item>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Using your input sample it outputs:
<root>
<item>
<list>
<name>a</name>
<vaue>a1</vaue>
</list>
<list>
<name>b</name>
<vaue>b5</vaue>
</list>
<list>
<name>c</name>
<vaue>c9</vaue>
</list>
<list>
<name>d</name>
<vaue>d66</vaue>
</list>
<type>1</type>
</item>
<item>
<list>
<name>a</name>
<vaue>a1</vaue>
</list>
<list>
<name>b</name>
<vaue>b5</vaue>
</list>
<list>
<name>c</name>
<vaue>c9</vaue>
</list>
<list>
<name>d</name>
<vaue>d66</vaue>
</list>
<type>2</type>
</item>
<item>
<list>
<name>a</name>
<vaue>a1</vaue>
</list>
<list>
<name>b</name>
<vaue>b5</vaue>
</list>
<list>
<name>c</name>
<vaue>c9</vaue>
</list>
<list>
<name>d</name>
<vaue>d66</vaue>
</list>
<type>1</type>
</item>
<item>
<list>
<name>a</name>
<vaue>a1</vaue>
</list>
<list>
<name>b</name>
<vaue>b5</vaue>
</list>
<list>
<name>c</name>
<vaue>c9</vaue>
</list>
<list>
<name>d</name>
<vaue>d66</vaue>
</list>
<type>2</type>
</item>
<item>
<list>
<name>a</name>
<vaue>a1</vaue>
</list>
<type>3</type>
</item>
</root>
Do note: your input sample doesn't match your expected output by the rules you've stated: there is no vaue
element with 'a9'
string value.
Upvotes: 1