1

I have this kind of xml

<?xml version="1.0"?>
<Data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Rows>
<Row>
  <Id>1</Id>
  <XColumns>
    <Name>Country</Name>
    <Value>Austria</Value>
  </XColumns>
  <XColumns>
    <Name>Region</Name>
    <Value>Europe</Value>
  </XColumns>
  <XColumns>
    <Name>Sector</Name>
    <Value>Information Technology</Value>
  </XColumns>
  <YColumns>
    <Name>Dataset 1</Name>
    <Value>14</Value>
  </YColumns>
  <YColumns>
    <Name>Dataset 2</Name>
    <Value>19</Value>
  </YColumns>
</Row>
<Row>
  <Id>2</Id>
  <XColumns>
    <Name>Country</Name>
    <Value>Bahamas</Value>
  </XColumns>
  <XColumns>
    <Name>Region</Name>
    <Value>North American</Value>
  </XColumns>
  <XColumns>
    <Name>Sector</Name>
    <Value>Information Technology</Value>
  </XColumns>
  <YColumns>
    <Name>Dataset 1</Name>
    <Value>1</Value>
  </YColumns>
  <YColumns>
    <Name>Dataset 2</Name>
    <Value>15</Value>
  </YColumns>
</Row>

I need to convert it to following XML using XSLT

<?xml version="1.0"?>
<data>
<categories>
 <category label="Austria"/>
 <category label="Bahamas"/>
</categories>
<dataset seriesName="DataSet 1">
 <set value="14"/>
 <set value="1"/>
</dataset>
<dataset seriesName="DataSet 2">
 <set value="19"/>
 <set value="15"/>
</dataset>

1 more thing, i have one variable called "category", if i pass category=Country so it will generate categories tag where label have value of country like Austria,Bahamas . if i pass category = region so it will generate categories tag where label have value of region like Europe, North American. So based upon category value i have to generate categories tag.

1
  • I have added to my answer a more efficient approach, if you are interested Commented Feb 19, 2013 at 13:18

1 Answer 1

2

The following code do what you try to achieve. However, depending on how the data set can change maybe is not he most efficient approach.

I am assuming that YColumns can appear in a different order and that we can find any number of datasets (not just 2) in the source file. If some of those restrictions can be removed, the solution could be simpler.

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

    <xsl:output method="xml" indent="yes" />

    <!-- Holds the category to be selected -->
    <xsl:param name="category"
               select="'Country'" />

    <!-- Process root element -->
    <xsl:template match="Data">
        <data>
            <xsl:apply-templates select="*" />
        </data>
    </xsl:template>

    <xsl:template match="Rows">
        <!-- Generate category based on parameter $category -->
        <categories>
            <xsl:apply-templates select="Row/XColumns[Name = $category]" />
        </categories>
        <!-- Generate data sets -->
        <xsl:apply-templates select="Row[1]/YColumns" />
    </xsl:template> 

    <!-- Generate category element -->  
    <xsl:template match="XColumns">
        <category label="{Value}" />
    </xsl:template>

    <!-- Generate dataset elements -->
    <xsl:template match="YColumns">
        <xsl:variable name="name" select="Name" />
        <dataset seriesName="{$name}">
            <xsl:for-each select="../../Row/YColumns[Name = $name]/Value">
                <set value="{.}" />
            </xsl:for-each>
        </dataset>
    </xsl:template>

</xsl:stylesheet>

UPDATE: a more efficient approach is using <xsl:key> to index all YColumn names. So you have to add

<xsl:key name="data-set" match="YColumns/Value" use="../Name" />

as a direct child of <xsl:stylesheet>

And change the expression following expression

../../Row/YColumns[Name = $name]/Value

to

key('data-set', $name)
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.