1

I have a source XML

<Cars>
  <Car>
    <Make>Fiat</Make>
    <Colors>
      <Color>RED</Color>
      <Color>BLUE</Color>
    </Colors>
  </Car>
  <Car>
    <Make>Volvo</Make>
    <Colors>
      <Color>RED</Color>
      <Color>WHITE</Color>
    </Colors>
  </Car>
  <Car>
    <Make>Renault</Make>
    <Colors>
      <Color>BLUE</Color>
      <Color>BLACK</Color>
    </Colors>
  </Car>
</Cars>

which I want to transform into something like

<Cars>
  <Detail>
    <Name>MakeName</Name>
    <Entry>Fiat</Entry>
    <Entry>Volvo</Entry>
    <Entry>Renault</Entry>
  </Detail>
  <Detail>
    <Name>AvailableColors</Name>
    <Entry>RED</Entry>
    <Entry>BLUE</Entry>
    <Entry>WHITE</Entry>
    <Entry>BLACK</Entry>
  </Detail>
<Cars>

I am new to XSL, and created one to do half of processing, but I am stuck with the getting of colors as separate elements in target

<xsl:template match="/">
  <Cars>
    <xsl:apply-templates />
  </Cars>
</xsl:template>

<xsl:template match="Cars">
  <xsl:apply-templates select="Car" />
</xsl:template>

<xsl:template match="Car">
  <Detail>
    <Name>MakeName</Name>
    <xsl:apply-templates select="Make" />
  </Detail>
</xsl:template>

<xsl:template match="Make">
  <Entry><xsl:value-of select"text()"/></Entry>
</xsl:template>

I am not able to create XSL for <Name>AvailableColors</Name>, I am quite new to XSL and any help is greatly appreciated

DaBler
  • 2,695
  • 2
  • 26
  • 46
JKV
  • 267
  • 4
  • 13
  • Side note: Is your business logic still valid after applying the transformation? I'd expect a WHITE Renault being available from your result but there is none in your source. – Filburt Jun 29 '12 at 11:38
  • We needed an xml that can give the car makes and colors as separate unique elements. The business logic was to split the source xml element 'Car' into two result xml elements 'Make' and 'Color' – JKV Jul 03 '12 at 04:56

2 Answers2

2

Here is an XSLT 1.0 stylesheet that shows how to eliminate duplicate colors using Muenchian grouping:

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

<xsl:output indent="yes"/>

<xsl:key name="k1" match="Car/Colors/Color" use="."/>

<xsl:template match="Cars">
  <xsl:copy>
    <Detail>
      <Name>MakeName</Name>
      <xsl:apply-templates select="Car/Make"/>
    </Detail>
    <Detail>
      <Name>AvailableColors</Name>
      <xsl:apply-templates select="Car/Colors/Color[generate-id() = generate-id(key('k1', .)[1])]"/>
    </Detail>
  </xsl:copy>
</xsl:template>

<xsl:template match="Car/Make | Colors/Color">
  <Entry>
    <xsl:value-of select="."/>
  </Entry>
</xsl:template>

</xsl:stylesheet>
Martin Honnen
  • 160,499
  • 6
  • 90
  • 110
0

See a generic "shredding" solution given in this answer:

https://stackoverflow.com/a/8597577/36305

Community
  • 1
  • 1
Dimitre Novatchev
  • 240,661
  • 26
  • 293
  • 431