Group by element and sum values XSLT - sum

I am new to XSLT and I am stuck on a problem. I've done some searches I read about Muenchian grouping but I do not know how to use it in this prorblem.
I am trying to write code in XSLT to read every teamName and sum the goals of each teams.
I am using XML v 1.0
Below is my current data file in XML:
<footballLeague>
<round num="1">
<match>
<local>
<teamName>AA</teamName>
<goals>0</goals>
</local>
<visitor>
<teamName>BB</teamName>
<goals>1</goals>
</visitor>
</match>
<match>
<local>
<teamName>CC</teamName>
<goals>1</goals>
</local>
<visitor>
<teamName>DD</teamName>
<goals>0</goals>
</visitor>
</match>
</round>
<round num="2">
<match>
<local>
<teamName>DD</teamName>
<goals>1</goals>
</local>
<visitor>
<teamName>AA</teamName>
<goals>1</goals>
</visitor>
</match>
<match>
<local>
<teamName>BB</teamName>
<goals>0</goals>
</local>
<visitor>
<teamName>CC</teamName>
<goals>1</goals>
</visitor>
</match>
</round>
<round num="3">
<match>
<local>
<teamName>DD</teamName>
<goals>0</goals>
</local>
<visitor>
<teamName>BB</teamName>
<goals>1</goals>
</visitor>
</match>
<match>
<local>
<teamName>CC</teamName>
<goals>0</goals>
</local>
<visitor>
<teamName>AA</teamName>
<goals>1</goals>
</visitor>
</match>
</round>
<round num="4">
<match>
<local>
<teamName>BB</teamName>
<goals>1</goals>
</local>
<visitor>
<teamName>AA</teamName>
<goals>0</goals>
</visitor>
</match>
<match>
<local>
<teamName>DD</teamName>
<goals>0</goals>
</local>
<visitor>
<teamName>CC</teamName>
<goals>1</goals>
</visitor>
</match>
</round>
<round num="5">
<match>
<local>
<teamName>AA</teamName>
<goals>1</goals>
</local>
<visitor>
<teamName>DD</teamName>
<goals>1</goals>
</visitor>
</match>
<match>
<local>
<teamName>CC</teamName>
<goals>1</goals>
</local>
<visitor>
<teamName>BB</teamName>
<goals>1</goals>
</visitor>
</match>
</round>
<round num="6">
<match>
<local>
<teamName>BB</teamName>
<goals>1</goals>
</local>
<visitor>
<teamName>DD</teamName>
<goals>0</goals>
</visitor>
</match>
<match>
<local>
<teamName>AA</teamName>
<goals>1</goals>
</local>
<visitor>
<teamName>CC</teamName>
<goals>0</goals>
</visitor>
</match>
</round>
</footballLeague>
The output I would like to achieve after running the XSLT is:
Team Name | Goals For | Goals against | Games Won | Tied Matches
AA | 4 | 4 | 2 | 2
BB | 5 | 2 | 4 | 1
CC | 4 | 3 | 3 | 1
DD | 2 | 6 | 0 | 2
Any help to get me started would be fantastic!

See if this can get you started:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="score" match="local|visitor" use="teamName" />
<xsl:template match="footballLeague">
<stats>
<xsl:for-each select="round/match/*[count(. | key('score', teamName)[1]) = 1]">
<team>
<xsl:copy-of select="teamName"/>
<goals-for>
<xsl:value-of select="sum(key('score', teamName)/goals)"/>
</goals-for>
<goals-against>
<xsl:value-of select="sum(key('score', teamName)[self::local]/../visitor/goals) + sum(key('score', teamName)[self::visitor]/../local/goals)"/>
</goals-against>
</team>
</xsl:for-each>
</stats>
</xsl:template>
</xsl:stylesheet>
Applied to your example, the result will be:
<?xml version="1.0" encoding="UTF-8"?>
<stats>
<team>
<teamName>AA</teamName>
<goals-for>4</goals-for>
<goals-against>4</goals-against>
</team>
<team>
<teamName>BB</teamName>
<goals-for>5</goals-for>
<goals-against>2</goals-against>
</team>
<team>
<teamName>CC</teamName>
<goals-for>4</goals-for>
<goals-against>3</goals-against>
</team>
<team>
<teamName>DD</teamName>
<goals-for>2</goals-for>
<goals-against>6</goals-against>
</team>
</stats>

Related

Having issue when there are identical keys in nodeset formed

My input xml is as below, I am facing issue when there are multiple identical keys present in a nodeset, its not forming proper output structure. I am using keys to form the nodeset by using ref attribute. I am making use of these <SL id="L1S1"> and <pit ref="L1S1"> to form nodesets. Id attribute of SL node(i.e <SL id="L1S1">) is formed using "L1" in <L Id="L1">. Also ref attribute of pit node(i.e <pit ref="L1S1">) is formed using "L1" in <L Id="L1">.
This solution works fine if I do not have multiple pit nodes with same reference number. I am using xslt1.0, and I have issue when multiple identical keys are found in nodeset.
Input xml as below
<root>
<L Id="L1">
<test>ed</test>
<SL id="L1S1">
<check>
<AId>1</AId>
</check>
</SL>
<SL id="L1S2">
<check>
<AId>2</AId>
</check>
</SL>
</L>
<cp>
<current>
<Amt>20154.00</Amt>
</current>
<pi>
<pit ref="L1S1">
<value>123</value>
</pit>
<pit ref="L1S1">
<value>234</value>
</pit>
<pit ref="L1S2">
<value>1232</value>
</pit>
</pi>
</cp>
</root>
Expected output should be:
<root>
<L Id="L1">
<SL id="L1S1">
<check>
<AId>1</AId>
</check>
</SL>
<pit ref="L1S1">
<value>123</value>
</pit>
</L>
<L Id="L1">
<SL id="L1S1">
<check>
<AId>1</AId>
</check>
</SL>
<pit ref="L1S1">
<value>234</value>
</pit>
</L>
<L Id="L1">
<SL id="L1S2">
<check>
<AId>2</AId>
</check>
</SL>
<pit ref="L1S2">
<value>1232</value>
</pit>
</L>
</root>
<xsl:key name="pit-SL" match="pit" use="#ref" />
<xsl:key name="pit-L" match="pit" use="substring(#ref,1,2)" />
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="L[SL]">
<xsl:apply-templates select="SL"/>
</xsl:template>
<xsl:template match="SL">
<L>
<xsl:copy-of select="parent::L/#Id"/>
<xsl:copy>
<xsl:copy-of select="#id"/>
<xsl:apply-templates select="node()"/>
<xsl:copy-of select="key('pit-SL',#id)"/>
</xsl:copy>
</L>
</xsl:template>
<xsl:template match="L[not(SL)]">
<xsl:apply-templates select="key('pit-L',#Id)">
<xsl:with-param name="L" select="."/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="pit">
<xsl:param name="L"/>
<L>
<xsl:copy-of select="$L/#Id"/>
<xsl:copy-of select="."/>
</L>
</xsl:template>
<xsl:template match="cp"/>
AFAICT, you could do:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="pit" match="pit" use="#ref" />
<xsl:template match="/root">
<xsl:copy>
<xsl:for-each select="L">
<xsl:variable name="Id" select="#Id" />
<xsl:for-each select="SL">
<xsl:variable name="SL" select="." />
<xsl:for-each select="key('pit', #id)">
<L>
<xsl:copy-of select="$Id"/>
<xsl:copy-of select="$SL"/>
<xsl:copy-of select="."/>
</L>
</xsl:for-each>
</xsl:for-each>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>

Form multiple parent node for each of its descendants

Im quite new to xslt and breaking my head over this issue. Can anyone please help me with this?
Please find the input XML, I need to look for text L1 in id field of L node and search sublocation id and pit ref has text L1 and form new L1 node and arrange sublocation and pit under each L1 nodes.
<root>
<L Id="L1">
<test>ed</test>
<SubLocation id="L1S1">
<check>
<AId>1</AId>
</check>
<MD>
<UnitNumber>1</UnitNumber>
</MD>
</SubLocation>
<SubLocation id="L1S2">
<check>
<AId>2</AId>
</check>
<MD>
<UnitNumber>2</UnitNumber>
</MD>
</SubLocation>
</L>
<L Id="L2">
<test>ed</test>
<SubLocation id="L2S1">
<check>
<AId>1</AId>
</check>
<MD>
<UnitNumber>1</UnitNumber>
</MD>
</SubLocation>
<SubLocation id="L2S2">
<check>
<AId>2</AId>
</check>
<MD>
<UnitNumber>2</UnitNumber>
</MD>
</SubLocation>
</L>
<cp>
<current>
<Amt>20154.00</Amt>
</current>
<pi>
<pit ref="L1S1">
<value>1232</value>
</pit>
<pit ref="L1S2">
<value>12345</value>
</pit>
<pit ref="L1S3">
<value>12387</value>
</pit>
<pit ref="L2S1">
<value>1232</value>
</pit>
<pit ref="L2S2">
<value>12345</value>
</pit>
</pi>
</cp>
</root>
I need the o/p in following format
<root>
<L1>
<SubLocation id="L1S1">
<check>
<AId>1</AId>
</check>
<MD>
<UnitNumber>1</UnitNumber>
</MD>
</SubLocation>
<pit ref="L1S1">
<value>1232</value>
</pit>
</L1>
<L1>
<SubLocation id="L1S2">
<check>
<AId>2</AId>
</check>
<MD>
<UnitNumber>2</UnitNumber>
</MD>
</SubLocation>
<pit ref="L1S2">
<value>12345</value>
</pit>
</L1>
<L2>
<SubLocation id="L2S1">
<check>
<AId>1</AId>
</check>
<MD>
<UnitNumber>1</UnitNumber>
</MD>
</SubLocation>
<pit ref="L2S1">
<value>1232</value>
</pit>
</L2>
<L2>
<SubLocation id="L2S2">
<check>
<AId>2</AId>
</check>
<MD>
<UnitNumber>2</UnitNumber>
</MD>
</SubLocation>
<pit ref="L2S2">
<value>12345</value>
</pit>
</L2>
</root>
This is my xslt
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="cpbyid" match="pit" use="#ref"/>
<xsl:key name="slById" match="SubLocation" use="#id"/>
<xsl:key name="locbyId" match="L" use="#id"/>
<xsl:template match="#*|node()" name="identity">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="L/*[#id]">
<L>
<xsl:value-of select="//L/#id"/>
<pifo>
<xsl:call-template name="subloc"></xsl:call-template>
<xsl:call-template name="identity"/>
</pifo>
</L>
</xsl:template>
<xsl:template match="pit/*[#ref]" name="subloc">
<inf>
<xsl:copy-of select="key('cpbyid', #id)"/>
<xsl:copy-of select="key('slById', #id)"/>
</inf>
</xsl:template>
</xsl:stylesheet>
I don't follow your description that well and I may be missing something. Is there a reason why you cannot do simply:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="pit" match="pit" use="#ref" />
<xsl:template match="/root">
<xsl:copy>
<xsl:for-each select="L/SubLocation">
<xsl:element name="{../#Id}">
<xsl:copy-of select="."/>
<xsl:copy-of select="key('pit', #id)"/>
</xsl:element>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>

Issue in forming node structure when multiple identical keys found in a nodeset

Scenario 1: L node having child node SL
Scenario 2: L node with no child node SL
Scenario 3: L node having child node SL and having multiple pit elements having attribute ref identical.
I need to form multiple L nodes if text "L1" () is found at other nodes like and . Id attribute of SL node(i.e ) is formed using "L1" in . Also ref attribute of pit node(i.e ) is formed using "L1" in , I need to check whether "L1" is present in either id attribute of SL or ref attribute of pit and form the desired output.
Input xml as below
<root>
<L Id="L1">
<test>ed</test>
<SL id="L1S1">
<check>
<AId>1</AId>
</check>
<MD>
<UnitNumber>1</UnitNumber>
</MD>
</SL>
<SL id="L1S2">
<check>
<AId>2</AId>
</check>
<MD>
<UnitNumber>2</UnitNumber>
</MD>
</SL>
</L>
<cp>
<current>
<Amt>20154.00</Amt>
</current>
<pi>
<pit ref="L1S1">
<value>123</value>
</pit>
<pit ref="L1S2">
<value>1232</value>
</pit>
</pi>
</cp>
</root>
Expected output should be:
<root>
<L Id="L1">
<SL id="L1S1">
<check>
<AId>1</AId>
</check>
<MD>
<UnitNumber>1</UnitNumber>
</MD>
</SL>
<pit ref="L1S1">
<value>123</value>
</pit>
</L>
<L Id="L1">
<SL id="L1S2">
<check>
<AId>2</AId>
</check>
<MD>
<UnitNumber>2</UnitNumber>
</MD>
</SL>
<pit ref="L1S2">
<value>1232</value>
</pit>
</L>
</root>
<root>
<L Id="L1">
<test>ed</test>
</L>
<cp>
<current>
<Amt>20154.00</Amt>
</current>
<pi>
<pit ref="L1S1">
<value>123</value>
</pit>
<pit ref="L1S2">
<value>1232</value>
</pit>
</pi>
</cp>
</root>
Expected output should be:
<root>
<L Id="L1">
<pit ref="L1S1">
<value>123</value>
</pit>
</L>
<L Id="L1">
<pit ref="L1S2">
<value>1232</value>
</pit>
</L>
</root>
Scenario 3:
Input xml as below
<root>
<L Id="L1">
<test>ed</test>
<SL id="L1S1">
<check>
<AId>1</AId>
</check>
<MD>
<UnitNumber>1</UnitNumber>
</MD>
</SL>
<SL id="L1S2">
<check>
<AId>2</AId>
</check>
<MD>
<UnitNumber>2</UnitNumber>
</MD>
</SL>
</L>
<cp>
<current>
<Amt>20154.00</Amt>
</current>
<pi>
<pit ref="L1S1">
<value>123</value>
</pit>
<pit ref="L1S1">
<value>234</value>
</pit>
<pit ref="L1S2">
<value>1232</value>
</pit>
<pit ref="L1S2">
<value>1</value>
</pit>
</pi>
</cp>
</root>
Expected output should be:
<root>
<L Id="L1">
<SL id="L1S1">
<check>
<AId>1</AId>
</check>
<MD>
<UnitNumber>1</UnitNumber>
</MD>
</SL>
<pit ref="L1S1">
<value>123</value>
</pit>
</L>
<L Id="L1">
<SL id="L1S1">
<check>
<AId>1</AId>
</check>
<MD>
<UnitNumber>1</UnitNumber>
</MD>
</SL>
<pit ref="L1S1">
<value>234</value>
</pit>
</L>
<L Id="L1">
<SL id="L1S2">
<check>
<AId>2</AId>
</check>
<MD>
<UnitNumber>2</UnitNumber>
</MD>
</SL>
<pit ref="L1S2">
<value>1232</value>
</pit>
</L>
<L Id="L1">
<SL id="L1S2">
<check>
<AId>2</AId>
</check>
<MD>
<UnitNumber>2</UnitNumber>
</MD>
</SL>
<pit ref="L1S2">
<value>1</value>
</pit>
</L>
</root>
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:key name="pit-SL" match="pit" use="#ref" />
<xsl:key name="pit-L" match="pit" use="substring(#ref,1,2)" />
<xsl:strip-space elements="*"/>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="L[SL]">
<xsl:apply-templates select="SL"/>
</xsl:template>
<xsl:template match="SL">
<L>
<xsl:copy-of select="parent::L/#Id"/>
<xsl:copy>
<xsl:copy-of select="#id"/>
<xsl:apply-templates select="node()"/>
<xsl:copy-of select="key('pit-SL',#id)"/>
</xsl:copy>
</L>
</xsl:template>
<xsl:template match="L[not(SL)]">
<xsl:apply-templates select="key('pit-L',#Id)">
<xsl:with-param name="L" select="."/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="pit">
<xsl:param name="L"/>
<L>
<xsl:copy-of select="$L/#Id"/>
<xsl:copy-of select="."/>
</L>
</xsl:template>
<xsl:template match="cp"/>
</xsl:stylesheet>
Iam facing issue in 3rd scenario, when there are multiple identical pit ref keys.
Here is an approach.
<xsl:key name="SLkey" match="SL" use="#id"/>
<xsl:key name="pitKey" match="pit" use="generate-id()"/>
<xsl:template match="root">
<xsl:copy>
<xsl:apply-templates select="#*|.//pit"/>
</xsl:copy>
</xsl:template>
<xsl:template match="pit">
<xsl:choose>
<!-- Is there an SL node match? -->
<xsl:when test="key('SLkey', #ref)[1]">
<xsl:apply-templates select="key('SLkey', #ref)[1]/.." mode="Loutput">
<xsl:with-param name="ref" select="#ref"/>
<xsl:with-param name="pitID" select="generate-id(.)"/>
</xsl:apply-templates>
</xsl:when>
<!-- Use the first L in the document. -->
<xsl:otherwise>
<xsl:apply-templates select="//L[1]" mode="Loutput">
<xsl:with-param name="ref" select="#ref"/>
<xsl:with-param name="pitID" select="generate-id(.)"/>
</xsl:apply-templates>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<!-- ********************** -->
<!-- Loutput mode templates -->
<!-- ********************** -->
<xsl:template match="node()|#*" mode="Loutput">
<xsl:copy>
<xsl:apply-templates select="node()|#*" mode="Loutput"/>
</xsl:copy>
</xsl:template>
<xsl:template match="L" mode="Loutput">
<xsl:param name="ref"/>
<xsl:param name="pitID"/>
<xsl:copy>
<xsl:apply-templates select="#*|SL[#id = $ref]" mode="Loutput"/>
<xsl:apply-templates select="key('pitKey', $pitID)" mode="Loutput"/>
</xsl:copy>
</xsl:template>

xslt 1.0 combinate two segments

how to combinate two or more segments to one segment at xslt 1.0?
I have two cases.
Case1:
If "QUALIFIER" at GRP/TXT is the same (for example: AAA) combinate this to one.
Correct:
QUALIFIER: AAA
TEXT: Test AAA rtetertertret
Case2:
Same should be at GRP/ITEM/TXT (for example: LIN)
Correct:
QUALIFIER: LIN
TEXT: Test LIN sdfsdfsfsf
<?xml version="1.0"?>
<SEEDELFOR>
<Test/>
<CNT>
<TRANSMISSION_DATE></TRANSMISSION_DATE>
<TRANSMISSION_TIME></TRANSMISSION_TIME>
<INTERCHANGE_CONTROL_NUMBER></INTERCHANGE_CONTROL_NUMBER>
<SENDER></SENDER>
<SENDER_QUALIFIER></SENDER_QUALIFIER>
<RECEIVER></RECEIVER>
<RECEIVER_QUALIFIER></RECEIVER_QUALIFIER>
<SYNTAX_IDENTIFIER></SYNTAX_IDENTIFIER>
<SYNTAX_VERSION></SYNTAX_VERSION>
<BGM></BGM>
<GRP>
<IDENTIFIER_BY></IDENTIFIER_BY>
<IDENTIFIER_SU></IDENTIFIER_SU>
<DATE_4></DATE_4>
<REF_ON></REF_ON>
<ADD>
<QUALIFIER></QUALIFIER>
<IDENTIFIER></IDENTIFIER>
<AGENCY_CODE></AGENCY_CODE>
<CONTACT>
<QUALIFIER></QUALIFIER>
<NUMBER></NUMBER>
</CONTACT>
<CONTACT>
<QUALIFIER></QUALIFIER>
<NUMBER></NUMBER>
</CONTACT>
<CONTACT>
<QUALIFIER></QUALIFIER>
<NUMBER></NUMBER>
</CONTACT>
</ADD>
<ADD>
<QUALIFIER></QUALIFIER>
<IDENTIFIER></IDENTIFIER>
<AGENCY_CODE></AGENCY_CODE>
</ADD>
<TXT>
<QUALIFIER>AAA</QUALIFIER>
<TEXT>Test AAA</TEXT>
</TXT>
<TXT>
<QUALIFIER>AAA</QUALIFIER>
<TEXT>rtetertertret</TEXT>
</TXT>
<TRANSPORT_DETAILS>
<ADDITIONAL_DETAILS>
<QUALIFIER></QUALIFIER>
<DETAILS></DETAILS>
</ADDITIONAL_DETAILS>
</TRANSPORT_DETAILS>
<TRANSPORT_DETAILS>
<ADDITIONAL_DETAILS>
<QUALIFIER></QUALIFIER>
<DETAILS></DETAILS>
</ADDITIONAL_DETAILS>
</TRANSPORT_DETAILS>
<TRANSPORT_DETAILS>
<ADDITIONAL_DETAILS>
<QUALIFIER></QUALIFIER>
<DETAILS></DETAILS>
</ADDITIONAL_DETAILS>
</TRANSPORT_DETAILS>
<ITEM>
<ITEM_NUMBER_SA></ITEM_NUMBER_SA>
<QUANTITY></QUANTITY>
<QUANTITY_UNIT></QUANTITY_UNIT>
<LINE_ITEM_NUMBER>2</LINE_ITEM_NUMBER>
<TXT>
<QUALIFIER>LIN</QUALIFIER>
<TEXT>Test LIN</TEXT>
</TXT>
</ITEM>
<ITEM>
<ITEM_NUMBER_SA></ITEM_NUMBER_SA>
<QUANTITY></QUANTITY>
<QUANTITY_UNIT></QUANTITY_UNIT>
<LINE_ITEM_NUMBER>1</LINE_ITEM_NUMBER>
<TXT>
<QUALIFIER>LIN</QUALIFIER>
<TEXT>Test LIN</TEXT>
</TXT>
<TXT>
<QUALIFIER>LIN</QUALIFIER>
<TEXT>sdfsdfsfsf</TEXT>
</TXT>
</ITEM>
</GRP>
</CNT>
</SEEDELFOR>
Correct output should be:
<?xml version="1.0"?>
<SEEDELFOR>
<Test/>
<CNT>
<TRANSMISSION_DATE></TRANSMISSION_DATE>
<TRANSMISSION_TIME></TRANSMISSION_TIME>
<INTERCHANGE_CONTROL_NUMBER></INTERCHANGE_CONTROL_NUMBER>
<SENDER></SENDER>
<SENDER_QUALIFIER></SENDER_QUALIFIER>
<RECEIVER></RECEIVER>
<RECEIVER_QUALIFIER></RECEIVER_QUALIFIER>
<SYNTAX_IDENTIFIER></SYNTAX_IDENTIFIER>
<SYNTAX_VERSION></SYNTAX_VERSION>
<BGM></BGM>
<GRP>
<IDENTIFIER_BY></IDENTIFIER_BY>
<IDENTIFIER_SU></IDENTIFIER_SU>
<DATE_4></DATE_4>
<REF_ON></REF_ON>
<ADD>
<QUALIFIER></QUALIFIER>
<IDENTIFIER></IDENTIFIER>
<AGENCY_CODE></AGENCY_CODE>
<CONTACT>
<QUALIFIER></QUALIFIER>
<NUMBER></NUMBER>
</CONTACT>
<CONTACT>
<QUALIFIER></QUALIFIER>
<NUMBER></NUMBER>
</CONTACT>
<CONTACT>
<QUALIFIER></QUALIFIER>
<NUMBER></NUMBER>
</CONTACT>
</ADD>
<ADD>
<QUALIFIER></QUALIFIER>
<IDENTIFIER></IDENTIFIER>
<AGENCY_CODE></AGENCY_CODE>
</ADD>
<TXT>
<QUALIFIER>AAA</QUALIFIER>
<TEXT>Test AAA rtetertertret</TEXT>
</TXT>
<TRANSPORT_DETAILS>
<ADDITIONAL_DETAILS>
<QUALIFIER></QUALIFIER>
<DETAILS></DETAILS>
</ADDITIONAL_DETAILS>
</TRANSPORT_DETAILS>
<TRANSPORT_DETAILS>
<ADDITIONAL_DETAILS>
<QUALIFIER></QUALIFIER>
<DETAILS></DETAILS>
</ADDITIONAL_DETAILS>
</TRANSPORT_DETAILS>
<TRANSPORT_DETAILS>
<ADDITIONAL_DETAILS>
<QUALIFIER></QUALIFIER>
<DETAILS></DETAILS>
</ADDITIONAL_DETAILS>
</TRANSPORT_DETAILS>
<ITEM>
<ITEM_NUMBER_SA></ITEM_NUMBER_SA>
<QUANTITY></QUANTITY>
<QUANTITY_UNIT></QUANTITY_UNIT>
<LINE_ITEM_NUMBER>2</LINE_ITEM_NUMBER>
<TXT>
<QUALIFIER>LIN</QUALIFIER>
<TEXT>Test LIN</TEXT>
</TXT>
</ITEM>
<ITEM>
<ITEM_NUMBER_SA></ITEM_NUMBER_SA>
<QUANTITY></QUANTITY>
<QUANTITY_UNIT></QUANTITY_UNIT>
<LINE_ITEM_NUMBER>1</LINE_ITEM_NUMBER>
<TXT>
<QUALIFIER>LIN</QUALIFIER>
<TEXT>Test LIN sdfsdfsfsf</TEXT>
</TXT>
</ITEM>
</GRP>
</CNT>
</SEEDELFOR>
Best regards
Julian
It can be achievable as following in XSLT 1.0:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:key name="qualifierKey" match="/SEEDELFOR/CNT/GRP//TXT" use="QUALIFIER" />
<xsl:key name="qualifierTextKey" match="/SEEDELFOR/CNT/GRP//TXT" use="concat(QUALIFIER, '|', TEXT)" />
<xsl:key name="itemTxtKey" match="/SEEDELFOR/CNT/GRP/ITEM/TXT" use="concat(generate-id(parent::*), QUALIFIER, '|', TEXT)" />
<xsl:template match="node() | #*">
<xsl:copy>
<xsl:apply-templates select="node() | #*" />
</xsl:copy>
</xsl:template>
<xsl:template match="TXT[position() > 1]" />
<xsl:template match="/SEEDELFOR/CNT/GRP/ITEM/TXT[following-sibling::*[1]][generate-id(.) = generate-id(key('itemTxtKey', concat(generate-id(parent::*), QUALIFIER, '|', TEXT))[1])]
| /SEEDELFOR/CNT/GRP/TXT[following-sibling::*[1]][generate-id() = generate-id(key('qualifierKey',QUALIFIER)[1])]">
<TXT>
<QUALIFIER>
<xsl:value-of select="normalize-space(QUALIFIER)" />
</QUALIFIER>
<TEXT>
<xsl:variable name="count" select="count(key('qualifierKey',QUALIFIER)[generate-id() = generate-id(key('qualifierTextKey', concat(QUALIFIER, '|', TEXT))[1])])" />
<xsl:for-each select="key('qualifierKey',QUALIFIER)[generate-id() = generate-id(key('qualifierTextKey', concat(QUALIFIER, '|', TEXT))[1])]">
<xsl:value-of select="normalize-space(TEXT)" />
<xsl:if test="$count != position()"><xsl:value-of select="' '"></xsl:value-of></xsl:if>
</xsl:for-each>
</TEXT>
</TXT>
</xsl:template>
</xsl:stylesheet>
See output here: http://xsltfiddle.liberty-development.net/jyRYYib/2

NotApplicable Response is XACML policy

Why am i getting NotApplicable response in XACML policy ? Please find my XACML policy, request and response below. In my policy, i have main target element which matches username. I am using wso2is-5.1.0 for my testing.
XACML policy
<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicyId="TestPolicyWithTarget" RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable" Version="1.0">
<Target>
<AnyOf>
<AllOf>
<Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">abhishek</AttributeValue>
<AttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"></AttributeDesignator>
</Match>
</AllOf>
</AnyOf>
</Target>
<Rule Effect="Permit" RuleId="TestRule">
<Target>
<AnyOf>
<AllOf>
<Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">foo1</AttributeValue>
<AttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"></AttributeDesignator>
</Match>
</AllOf>
</AnyOf>
<AnyOf>
<AllOf>
<Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">read</AttributeValue>
<AttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"></AttributeDesignator>
</Match>
</AllOf>
</AnyOf>
</Target>
<Condition>
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:not">
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:any-of">
<Function FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal"></Function>
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">abhishek</AttributeValue>
<AttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"></AttributeDesignator>
</Apply>
</Apply>
</Condition>
</Rule>
</Policy>
XACML Request
<Request xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" CombinedDecision="false" ReturnPolicyIdList="false">
<Attributes Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource">
<Attribute AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" IncludeInResult="false">
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">foo1</AttributeValue>
</Attribute>
</Attributes>
<Attributes Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject">
<Attribute AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" IncludeInResult="false">
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">abhishek</AttributeValue>
</Attribute>
</Attributes>
<Attributes Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action">
<Attribute AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" IncludeInResult="false">
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">read</AttributeValue>
</Attribute>
</Attributes>
</Request>
XACML Response
<Response xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17">
<Result>
<Decision>NotApplicable</Decision>
<Status>
<StatusCode Value="urn:oasis:names:tc:xacml:1.0:status:ok"/>
</Status>
</Result>
</Response>
I tested your policy in the Axiomatics Policy Server and I also get NotApplicable. What effect were you expecting? The policy behaves correctly. The Policy target and the Rule target are both matched.
The condition is also matched but given you use a not() function, it becomes false and therefore the rule does not apply which leads to NotApplicable.
If you want Deny back, then you need to have a catch all Deny rule after the Permit rule.
And here is the code.
<xacml3:Policy xmlns:xacml3="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicyId="TestPolicyWithTarget" Version="1.0" RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable">
<xacml3:Description/>
<xacml3:PolicyDefaults>
<xacml3:XPathVersion>http://www.w3.org/TR/1999/REC-xpath-19991116</xacml3:XPathVersion>
</xacml3:PolicyDefaults>
<xacml3:Target>
<xacml3:AnyOf>
<xacml3:AllOf>
<xacml3:Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<xacml3:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">abhishek</xacml3:AttributeValue>
<xacml3:AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
</xacml3:Match>
</xacml3:AllOf>
</xacml3:AnyOf>
</xacml3:Target>
<xacml3:Rule RuleId="TestRule" Effect="Permit">
<xacml3:Target>
<xacml3:AnyOf>
<xacml3:AllOf>
<xacml3:Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<xacml3:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">foo1</xacml3:AttributeValue>
<xacml3:AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
</xacml3:Match>
</xacml3:AllOf>
</xacml3:AnyOf>
<xacml3:AnyOf>
<xacml3:AllOf>
<xacml3:Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<xacml3:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">read</xacml3:AttributeValue>
<xacml3:AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
</xacml3:Match>
</xacml3:AllOf>
</xacml3:AnyOf>
</xacml3:Target>
<xacml3:Condition >
<xacml3:Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:not">
<xacml3:Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:any-of">
<xacml3:Function FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal"/>
<xacml3:AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">abhishek</xacml3:AttributeValue>
<xacml3:AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
</xacml3:Apply>
</xacml3:Apply>
</xacml3:Condition>
</xacml3:Rule>
<xacml3:Rule RuleId="0e96abf0-e2f5-495b-8df1-bb3f2987e949" Effect="Deny">
<xacml3:Description>Catch all</xacml3:Description>
<xacml3:Target/>
</xacml3:Rule>
</xacml3:Policy>