0

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

1
  • 1
    It always helps if you show us your existing code and tell us exactly which XSLT processor and/or XSLT version you use. Commented Jan 16, 2020 at 13:52

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.