I am usually good at XSLT programming but this has got me stumped. I think it is related to Muenchian Grouping but I am not sure as when I try the result is not what I want so I maybe wrong here. I have the following XML that I need to transform into the output XML. I am restricted to using XSLT 1.0.
Input XML
<ns2:ListOfAssetMgmt-AssetXaQe xmlns:ns2="http://system.com/CustomUI">
<ns3:AssetMgmt-AssetXaQe xmlns:ns3="http://www.system.com/xml/QE%20%%20%Points">
<ns3:Id>1</ns3:Id>
<ns3:Name2>Direction</ns3:Name2>
<ns3:TextValue>Injection</ns3:TextValue>
</ns3:AssetMgmt-AssetXaQe>
<ns3:AssetMgmt-AssetXaQe xmlns:ns3="http://www.system.com/xml/QE%20%%20%Points">
<ns3:Id>1</ns3:Id>
<ns3:Name2>MeterType</ns3:Name2>
<ns3:TextValue>YMR</ns3:TextValue>
</ns3:AssetMgmt-AssetXaQe>
<ns3:AssetMgmt-AssetXaQe xmlns:ns3="http://www.system.com/xml/QE%20%%20%Points">
<ns3:Id>2</ns3:Id>
<ns3:Name2>LoadProfile</ns3:Name2>
<ns3:TextValue>Wind</ns3:TextValue>
</ns3:AssetMgmt-AssetXaQe>
<ns3:AssetMgmt-AssetXaQe xmlns:ns3="http://www.system.com/xml/QE%20%%20%Points">
<ns3:Id>2</ns3:Id>
<ns3:Name2>Direction</ns3:Name2>
<ns3:TextValue>Rotation</ns3:TextValue>
</ns3:AssetMgmt-AssetXaQe>
<ns3:AssetMgmt-AssetXaQe xmlns:ns3="http://www.system.com/xml/QE%20%%20%Points">
<ns3:Id>2</ns3:Id>
<ns3:Name2>MeterType</ns3:Name2>
<ns3:TextValue>ZMR</ns3:TextValue>
</ns3:AssetMgmt-AssetXaQe>
</ns3:ListOfAssetMgmt-AssetXaQe>
Output XML
<Assets>
<QuotingEngineServicePointAssets>
<MeterConfigurationId>1</MeterConfigurationId>
<Direction>Injection</Direction>
<MeterType>YMR</MeterType>
<TimeOfUse></TimeOfUse>
<Segment></Segment>
<Tension></Tension>
<ReadingFrequency></ReadingFrequency>
<BillingFrequency></BillingFrequency>
<LoadProfile></LoadProfile>
<LocalProduction></LocalProduction>
<DistributionTariff></DistributionTariff>
</QuotingEngineServicePointAssets>
<QuotingEngineServicePointAssets>
<MeterConfigurationId>2</MeterConfigurationId>
<Direction>Rotation</Direction>
<MeterType>ZMR</MeterType>
<TimeOfUse></TimeOfUse>
<Segment></Segment>
<Tension></Tension>
<ReadingFrequency></ReadingFrequency>
<BillingFrequency></BillingFrequency>
<LoadProfile>Wind</LoadProfile>
<LocalProduction></LocalProduction>
<DistributionTariff></DistributionTariff>
</QuotingEngineServicePointAssets>
</Assets>
The other tags like TimeOfUse, Segment etc. may also need to be populated if they exist on the input XML. If they don't exist on the Input XML then the element should not be output on the Output XML but I have shown them here for what could be output. Any assistance would be very much appreciated.
I agree with michael.hor257k in the statement that your question does not contain a textual description of what you want to achieve. Please always include that to help us help you.
Nevertheless, I looked at your inputs and outputs and think I got an idea on the basic logic behind the examples.
I would build the process in two stages:
<!-- get distinct IDs, variable contains <id>1</id><id>2</id> -->
<xsl:variable name="distinctValues">
<xsl:for-each select="//AssetMgmt-AssetXaQe">
<xsl:variable name="ctx1" select="." />
<!-- filter out IDs that already occured to list them only once -->
<xsl:if test="not(preceding-sibling::AssetMgmt-AssetXaQe[Id/text() = $ctx1/Id/text()])">
<id><xsl:value-of select="$ctx1/Id/text()" /></id>
</xsl:if>
</xsl:for-each>
</xsl:variable>
<xsl:key name="AssetMgmt-by-Id" match="AssetMgmt-AssetXaQe" use="Id" />
<xsl:for-each select="AssetMgmt-AssetXaQe[count(. | key('AssetMgmt-by-Id', Id)[1]) = 1]">
<!-- do whatever needs to be done per unique ID -->
</for-each>
xslt:element
) named based on each Name2
-tags content:<xsl:variable name="$ctx2" select="." />
<xsl:for-each select="$distinctValues">
<QuotingEngineServicePointAssets>
<MeterConfigurationId>
<xsl:value-of select="." />
</MeterConfigurationId>
<!-- iterate over all the entries that belong to this ID -->
<xsl:for-each select="$ctx2//AssetMgmt-AssetXaQe[Id/text() = .]">
<!-- dynamically generate tags based on the content of the Name2-Tag -->
<xsl:element name="{./Name2}">
<xsl:value-of select="./TextValue">
</xsl:element>
</xsl:for-each>
</QuotingEngineServicePointAssets>
</xsl:for-each>
That should do the trick. I left the trouble regarding namespaces for you, good luck!