INPUT:
<?xml version="1.0" encoding="UTF-8"?>
<output>
<input>
<!--details-->
</input>
<meta2>
<tag>
<output_getquerydata>
<queries>
<query name="part1">
<parameters>
<!--details-->
</parameters>
<queryErrors>
<!--details-->
</queryErrors>
<queryResults>
<record id="1">
<column name="VRIdTask">1</column>
<column name="MSTP">22</column>
<column name="VRPlanId">11310224</column>
<column name="MSONPC">221</column>
</record>
<record id="2">
<column name="VRIdTask">1</column>
<column name="MSTP">22</column>
<column name="VRPlanId">11310224</column>
<column name="MSONPC">2211</column>
</record>
<record id="3">
<column name="VRIdTask">3</column>
<column name="MSTP"/>
<column name="VRPlanId">11310337</column>
<column name="MSONPC"/>
</record>
<record id="4">
<column name="VRIdTask">2</column>
<column name="MSTP"/>
<column name="VRPlanId">11310281</column>
<column name="MSONPC">2221</column>
</record>
<record id="5">
<column name="VRIdTask">4</column>
<column name="MSTP">33</column>
<column name="VRPlanId">11310281</column>
<column name="MSONPC">222221</column>
</record>
<record id="6">
<column name="VRIdTask">4</column>
<column name="MSTP">331</column>
<column name="VRPlanId">11310281</column>
<column name="MSONPC">222221</column>
</record>
</queryResults>
</query>
</queries>
</output_getquerydata>
</tag>
</meta2>
</output>
XSL:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="k" match="output/meta2/tag/output_getquerydata/queries/query/queryResults/record" use="./column[@name='VRPlanId']"/>
<xsl:template match="@*|node()">
<xsl:variable name="distinctOrder" select="//record[string(column[@name='VRPlanId'])][count(. | key('k', column[@name='VRPlanId'])[1]) >1]"/>
<xsl:if test="count(key('k', .//column[@name='VRPlanId'])) >0 or //queryError">
<Cdo>
<parameters>
<xsl:for-each select="$distinctOrder">
<task id="{concat(column[@name='MSTP'],',',column[@name='MSONPC'])}"/>
<action id="{column[@name='VRPlanId']}"/>
</xsl:for-each>
<xsl:for-each select="key('k', column[@name='VRPlanId'])">
<action id="{column[@name='VRPlanId']}"/>
</xsl:for-each>
</parameters>
</Cdo>
</xsl:if>
</xsl:template>
<xsl:template match="input"/>
</xsl:stylesheet>
Hello everyone,
Thanks for your help. The goal is to check for every distinct VRPlanID value that we build the tag Group the corresponding MSTP, MSONPC (distinct) if they're not null/empty in the id part of the tag. So, we group after VRPlanID, then get the distinct values from each record from MSTP/MSONPC. If they're empty then just build a dummy / null message/tag. (not done)
So, the desired output would be:
<output>
<Cdo>
<parameters>
<task id="22,221,2211"/>
<action id="1131024"/>
</parameters>
</Cdo>
<Cdo>
<parameters>
<task id="2221/>
<action id="999"/>
</parameters>
</Cdo>
<Cdo>
<parameters>
<task id="33,331,222221"/>
<action id="11310281"/>
</parameters>
</Cdo>
</output>
Later edit:
with this:
<!--parameter to filter per VRPlanId-->
<xsl:param name="param.VRPlanId"/>
<xsl:variable name="var.mstp">
<xsl:for-each select="/output/meta2/tag/output_getquerydata/queries/query/queryResults/record[column[@name='VRPlanId'] = $param.VRPlanId]">
<!--preventing empty blocks and duplicates for MSTP-->
<xsl:if test="string-length(column[@name='MSTP']) >0
and not(preceding::record[column[@name='MSTP']/text() = current()/column[@name='MSTP']/text()])">
<xsl:value-of select="column[@name='MSTP']"/>
</xsl:if>
</xsl:for-each>
</xsl:variable>
<!--concat all non-duplicates MSTP and MSONPC without last delimiter-->
<xsl:value-of select="$var.mstp"/>
</xsl:template>
I get the concatenated results, but not in separate tags
<parameters>
<task id="131957513196231319667"/>
<action id="11310281"/>
</parameters>
I think it is better to prevent duplicates in MSTP and MSONPC and put them into one template where input parameter will be non-duplicated VRPlanId as in XSL below:
You have edited your version of XML but in case of XML below:
The result is:
NOTE! In proposed XSL there is validation for empty values, if you will require include them just remove that validations.
In case when it is required to use each attribute value in separate task tag then you can create task blocks structure in separate template and call it in parameters block as below:
Then when you will check it with XML above the result will be as below:
Of course you can add blank values validation where it is required.
Hope it will help with your case.