Rg90
Rg90

Reputation: 581

XSLT - Merge child records

I have an XML in this format:

<Records>
  <Record id="1" type="1">
    <Field type="1">2013-Week 41</Field>
    <Field type="6">219</Field>
    <Field type="7">ABC</Field>
  </Record>
  <Record id="1" type="2">
    <Field type="1">2013-Week 41</Field>
    <Field type="6">220</Field>
    <Field type="7">PQR</Field>
  </Record>
  <Record id="1" type="3">
    <Field type="1">2013-Week 42</Field>
    <Field type="6">221</Field>
    <Field type="7">XYZ</Field>
  </Record>
</Records>

I want to merge all the Record elements according to the Week, say 2013-Week 41 will contain 219, 220 as child records, 2013-Wee 42 will contain 221 and so on.

My desired output is this:

<Records>
    <Week>
        <Name>2013-Week 41</Name>
        <Week_Task>
            <Value>219</Value>
            <Name>ABC</Name>
        </Week_Task>
        <Week_Task>
            <Value>220</Value>
            <Name>PQR</Name>
        </Week_Task>
    </Week>
    <Week>
        <Name>2013-Week 42</Name>
        <Week_Task>
            <Value>221</Value>
            <Name>XYZ</Name>
        </Week_Task>
    </Week>
</Records>

How can I use group by or distinct elements to achieve this? I need to use XSLT 1.0.

Upvotes: 0

Views: 297

Answers (1)

Martin Honnen
Martin Honnen

Reputation: 167571

Well if you want to use XSLT 1.0 you have neither group-by nor distinct-values as that are XSLT 2.0 features.

With XSLT 1.0 you need to use Muenchian grouping:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output indent="yes"/>

<xsl:key name="by-week" match="Record" use="Field[@type = 1]"/>

<xsl:template match="Records">
  <xsl:copy>
    <xsl:apply-templates select="Record[generate-id() = generate-id(key('by-week', Field[@type = 1])[1])]"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="Record">
  <Week>
    <Name><xsl:value-of select="Field[@type = 1]"/></Name>
    <xsl:apply-templates select="key('by-week', Field[@type = 1])" mode="task"/>
  </Week>
</xsl:template>

<xsl:template match="Record" mode="task">
  <Week_Task>
    <xsl:apply-templates select="Field[not(@type = 1)]"/>
  </Week_Task>
</xsl:template>

<xsl:template match="Field[@type = 6]">
  <Value><xsl:value-of select="."/></Value>
</xsl:template>

<xsl:template match="Field[@type = 7]">
  <Name><xsl:value-of select="."/></Name>
</xsl:template>

</xsl:stylesheet>

Upvotes: 1

Related Questions