Kapil
Kapil

Reputation: 832

Filter and Group in XSLT

I am trying to filter data and then group using XSLT. Here is my XML

    <?xml version="1.0" encoding="UTF-8"?>
<AccumulatedOutput>
    <root>
        <Header>
            <Add>true</Add>
            <Name>Subscriber</Name>
            <Value>SAC</Value>
        </Header>
    </root>
    <root>
        <Header>
            <Add>true</Add>
            <Name>System</Name>
            <Value>CBP</Value>
        </Header>
    </root>
    <root>
        <Header>
            <Add>false</Add>
            <Name>Subscriber</Name>
            <Value>SAC</Value>
        </Header>
    </root>
</AccumulatedOutput>

What I want to do is that group based on Header/Name and but remove the group in which Header/Add is false. So in above example I there will be two groups created (one for Name=Subscriber and other for Name=System) but since the first group(with Name=Subscriber) contains Add=false , I want to ignore that and my output should only have one node in it , like below

<?xml version = "1.0" encoding = "UTF-8"?>
<root>
    <Header>
        <Name>System</Name>
        <Value>CBP</Value>
        <Add>true</Add>
    </Header>
</root> 

I tried using group by method but I can't figure out a way to filter it. It will be a great help if someone can give me some pointers

Thanks

Upvotes: 1

Views: 1263

Answers (2)

Dimitre Novatchev
Dimitre Novatchev

Reputation: 243459

No explicit XSLT conditional instructions:

<xsl:template match="/*">
    <root>
        <xsl:for-each-group group-by="Name" select=
        "root/Header[for $n in string(Name)
                      return every $h in /*/root/Header[Name eq $n] 
                                     satisfies not($h/Add eq 'false')]">
              <xsl:sequence select="current-group()"/>
        </xsl:for-each-group>
    </root>
</xsl:template>

Upvotes: 1

michael.hor257k
michael.hor257k

Reputation: 116993

In XSLT 2.0, you could do:

<xsl:template match="/AccumulatedOutput">
    <root>
        <xsl:for-each-group select="root/Header" group-by="Name">
            <xsl:if test="not(current-group()/Add='false')">
                <xsl:copy-of select="current-group()"/>
            </xsl:if>
        </xsl:for-each-group>
    </root>
</xsl:template>

Upvotes: 3

Related Questions