Tricky XSLT Transformation

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • boetke
    New Member
    • Jan 2010
    • 1

    Tricky XSLT Transformation

    Hi all,

    I am attempting to create an xslt transformation which I am having trouble with. I am fairly new to xslt and am having a hard time getting my head around it. The original xml file looks like this:

    Code:
    <DataSet ID="-5480">
    	<ObsGroup>
    		<ClsItem name="AGE">2099</ClsItem>
    		<ClsItem name="COMB_DATA">20</ClsItem>
    		<ClsItem name="SEX">2</ClsItem>
    		<ClsItem name="STATE">0</ClsItem>
    		<ClsItem name="MARITAL_STATUS">3</ClsItem>
    		<ParItem name="UNEMPLOYMENT_RATE">23.34</ParItem>
    		<ParItem name="LABFORCE_FULL_TIME">2292.7071594375</ParItem>
    		<TimeItem name="TIME_CODE">2447</TimeItem>
    	</ObsGroup>
    	<ObsGroup>
    		<ClsItem name="AGE">2099</ClsItem>
    		<ClsItem name="COMB_DATA">20</ClsItem>
    		<ClsItem name="SEX">2</ClsItem>
    		<ClsItem name="STATE">0</ClsItem>
    		<ClsItem name="MARITAL_STATUS">3</ClsItem>
    		<ParItem name="UNEMPLOYMENT_RATE">23.66</ParItem>
    		<ParItem name="LABFORCE_FULL_TIME">2300.72108466884</ParItem>
    		<TimeItem name="TIME_CODE">2451</TimeItem>
    	</ObsGroup>
    	<ObsGroup>
    		<ClsItem name="AGE">2099</ClsItem>
    		<ClsItem name="COMB_DATA">20</ClsItem>
    		<ClsItem name="SEX">2</ClsItem>
    		<ClsItem name="STATE">0</ClsItem>
    		<ClsItem name="MARITAL_STATUS">4</ClsItem>
    		<ParItem name="UNEMPLOYMENT_RATE">23.77</ParItem>
    		<ParItem name="LABFORCE_FULL_TIME">2353.4791599122</ParItem>
    		<TimeItem name="TIME_CODE">2447</TimeItem>
    	</ObsGroup>
    	<ObsGroup>
    		<ClsItem name="AGE">2099</ClsItem>
    		<ClsItem name="COMB_DATA">20</ClsItem>
    		<ClsItem name="SEX">2</ClsItem>
    		<ClsItem name="STATE">0</ClsItem>
    		<ClsItem name="MARITAL_STATUS">4</ClsItem>
    		<ParItem name="UNEMPLOYMENT_RATE">23.88</ParItem>
    		<ParItem name="LABFORCE_FULL_TIME">2335.71727933868</ParItem>
    		<TimeItem name="TIME_CODE">2451</TimeItem>
    	</ObsGroup>
    </DataSet>
    And I want the transformation to group by the clsitem and one paritem per group, as 'measures'. This group will then have all the timeitem elements related to it. Example output:

    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <GenericData>
    	<DataSet>
    		<Series>
    			<SeriesKey>	
    				<Value concept="MEASURES" value="UNEMPLOYMENT_RATE"/>
    				<Value concept="AGE" value="2099"/>
    				<Value concept="COMB_DATA" value="20"/>
    				<Value concept="SEX" value="2"/>
    				<Value concept="STATE" value="0"/>
    				<Value concept="MARITAL_STATUS" value="3"/>
    			</SeriesKey>
    			<Obs>
    				<Time>2447</Time>
    				<ObsValue value="23.34"/>
    			</Obs>
    			<Obs>
    				<Time>2451</Time>
    				<ObsValue value="23.66"/>
    			</Obs>
    		</Series>
    		<Series>
    			<SeriesKey>
    				<Value concept="MEASURES" value="LABFORCE_FULL_TIME"/>
    				<Value concept="AGE" value="2099"/>
    				<Value concept="COMB_DATA" value="20"/>
    				<Value concept="SEX" value="2"/>
    				<Value concept="STATE" value="0"/>
    				<Value concept="MARITAL_STATUS" value="3"/>
    			</SeriesKey>
    			<Obs>
    				<Time>2477</Time>
    				<ObsValue value="2292.7071594375"/>
    			</Obs>
    			<Obs>
    				<Time>2451</Time>
    				<ObsValue value="2300.72108466884"/>
    			</Obs>
    		</Series>
    		<Series>
    			<SeriesKey>
    				<Value concept="MEASURES" value="UNEMPLOYMENT_RATE"/>
    				<Value concept="AGE" value="2099"/>
    				<Value concept="COMB_DATA" value="20"/>
    				<Value concept="SEX" value="2"/>
    				<Value concept="STATE" value="0"/>
    				<Value concept="MARITAL_STATUS" value="4"/>
    			</SeriesKey>
    			<Obs>
    				<Time>2447</Time>
    				<ObsValue value="23.77"/>
    			</Obs>
    			<Obs>
    				<Time>2451</Time>
    				<ObsValue value="23.88"/>
    			</Obs>
    		</Series>		
    		<Series>
    			<SeriesKey>
    				<Value concept="MEASURES" value="LABFORCE_FULL_TIME"/>
    				<Value concept="AGE" value="2099"/>
    				<Value concept="COMB_DATA" value="20"/>
    				<Value concept="SEX" value="2"/>
    				<Value concept="STATE" value="0"/>
    				<Value concept="MARITAL_STATUS" value="4"/>
    			</SeriesKey>
    			<Obs>
    				<Time>2447</Time>
    				<ObsValue value="2353.4791599122"/>
    			</Obs>
    			<Obs>
    				<Time>2451</Time>
    				<ObsValue value="2335.71727933868"/>
    			</Obs>
    		</Series>
    	</DataSet>
    </GenericData>
    My xslt is not grouping them correctly and I think I am on the wrong path. I have tried several grouping functions also, but they don't look right. My closest useful attempt:

    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions">
    	<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    	<xsl:template match="/">
    	<GenericData >
    	<DataSet>
    	<xsl:for-each select="DataSet/ObsGroup/ParItem">
    	    <Series>
    	        <SeriesKey>
    	            <Value>
    	               <xsl:attribute name="concept">MEASURES</xsl:attribute>
    	               <xsl:attribute name="value"><xsl:value-of select="@name" /></xsl:attribute>               
    	            </Value>
    	            <xsl:for-each select="../ClsItem">
    	            <Value>
    	               <xsl:attribute name="concept"><xsl:value-of select="@name" /></xsl:attribute>
    	               <xsl:attribute name="value"><xsl:value-of select="." /></xsl:attribute>               
    	            </Value>	            
    	            </xsl:for-each>
    	            <xsl:for-each select="../TimeItem">
    	               <Obs>
    	                  <Time><xsl:value-of select="." /></Time>
    	                  <ObsValue>
    	                     <xsl:attribute name="value"><xsl:value-of select="../ParItem" /></xsl:attribute>
    	                  </ObsValue>
    	               </Obs>
    	            </xsl:for-each>
    	        </SeriesKey>
    	    </Series>
    	</xsl:for-each>
    	</DataSet>
    	</GenericData>
    	</xsl:template>
    </xsl:stylesheet>
    Which doesn't group the time elements and also doesn't select the proper paritem value in the for-each loop.

    I am not sure how I should be approaching this. Anyone have any thoughts?
  • Dormilich
    Recognized Expert Expert
    • Aug 2008
    • 8694

    #2
    I think, you need something like Munchian Grouping

    Comment

    Working...