Jump to content

Help on XSLT


akamathb

Recommended Posts

Hi,need help in xslt usage...i have requirement to convert a xml to anaother xml using xslt:please help...input xml is :-<data jsxid="jsxroot"><record jsxid="100" slno="1" property="DISTRIBUTION" operator="=" value="UNITED KINGDOM"/><record jsxid="101" property="BRAND OWNER" operator="Contains" value="HOOK" /><record jsxid="102" property="" operator="" value="500ML" /> </data>i need the o/p as:-<defaultQuery><subQuery><condition><property>DISTRIBUTION</property><operator>=</operator><values><value>UNITED KINGDOM</value></values></condition><condition><property>BRAND OWNER</property><operator>contains</operator><values><value>HOOK</value><value>500ml</value></values></condition></subQuery></defaultQuery>

Link to comment
Share on other sites

It is not clear to me what determines when "record" elements are merged into a "condition". How is that determined? Is that because the 'property="BRAND OWNER" element is followed by an element where "property" and "operator" is empty?
Hi Martin,,thanks for replyFor each property != empty condition existsfor property==empty take the previous condition and update the value section onlyhope this helps
Link to comment
Share on other sites

Here is an XSLT 2.0 solution:

<xsl:stylesheet  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  xmlns:xs="http://www.w3.org/2001/XMLSchema"  exclude-result-prefixes="xs"  version="2.0">    <xsl:output indent="yes"/>    <xsl:template match="data">	<defaultQuery>	  <subQuery>		<xsl:for-each-group select="record" group-starting-with="record[normalize-space(@property)]">		  <condition>			<property><xsl:value-of select="@property"/></property>			<operator><xsl:value-of select="@operator"/></operator>			<values>			  <xsl:apply-templates select="current-group()"/>			</values>		  </condition>		</xsl:for-each-group>	  </subQuery>	</defaultQuery>  </xsl:template>    <xsl:template match="data/record">	<value><xsl:value-of select="@value"/></value>  </xsl:template>  </xsl:stylesheet>

You can run XSLT 2.0 stylesheets with XSLT 2.0 processors like Saxon 9 (http://saxon.sourceforge.net/), AltovaXML (http://www.altova.com/altovaxml.html) or XQSharp (http://www.xqsharp.com/) or with various XML editors/IDEs like Stylus Studio or XML Spy.If you need an XSLT 1.0 solution then try

<xsl:stylesheet  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  version="1.0">    <xsl:output indent="yes"/>    <xsl:key name="k1" match="data/record[not(normalize-space(@property))]" 	use="generate-id(preceding-sibling::record[normalize-space(@property)][1])"/>	  <xsl:template match="data">	<defaultQuery>	  <subQuery>		<xsl:apply-templates select="record[normalize-space(@property)]" mode="group"/>	  </subQuery>	</defaultQuery>  </xsl:template>    <xsl:template match="data/record" mode="group">	<condition>	  <property><xsl:value-of select="@property"/></property>	  <operator><xsl:value-of select="@operator"/></operator>	  <values>		<xsl:apply-templates select=". | key('k1', generate-id())"/>	  </values>	</condition>  </xsl:template>    <xsl:template match="data/record">	<value><xsl:value-of select="@value"/></value>  </xsl:template>  </xsl:stylesheet>

Link to comment
Share on other sites

  • 2 weeks later...

Hey Martin.. Need Help Again...tried a lot but failed:(My Request xml is changed a bit again...additional property is "slno" and looks as follows<data jsxid="jsxroot"><record jsxid="100" slno="1" property="DISTRIBUTION" operator="=" value="UNITED KINGDOM"/><record jsxid="101" property="BRAND OWNER" operator="Contains" value="HOOK"/><record jsxid="102" property="" operator="" value="500ML"/> <record jsxid="100" slno="2" property="DISTRIBUTION2" operator="=" value="UNITED KINGDOM"/><record jsxid="101" property="BRAND OWNER2" operator="Contains" value="HOOK1"/><record jsxid="102" property="" operator="" value="500ML1"/> </data>o/p needed:-<?xml version="1.0"?><defaultQuery><subQuery slno=1><condition><property>DISTRIBUTION</property><operator>=</operator><values><value>UNITED KINGDOM</value></values></condition><condition><property>BRAND OWNER</property><operator>Contains</operator><values><value>HOOK</value><value>500ML</value></values></condition></subQuery><subQuery slno=2><condition><property>DISTRIBUTION2</property><operator>=</operator><values><value>UNITED KINGDOM</value></values></condition><condition><property>BRAND OWNER2</property><operator>Contains</operator><values><value>HOOK1</value><value>500ML1</value></values></condition></subQuery></defaultQuery>The SubQuery level will be for Each Slno..The rest remains the same as i explained u in the earlier thread..pls help

Link to comment
Share on other sites

Here is an updated XSLT 2.0 stylesheet:

<xsl:stylesheet  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  xmlns:xs="http://www.w3.org/2001/XMLSchema"  exclude-result-prefixes="xs"  version="2.0">    <xsl:output indent="yes"/>    <xsl:template match="data">	<defaultQuery>	  <xsl:for-each-group select="record" group-starting-with="record[@slno]">		<subQuery slno="{@slno}">		  <xsl:for-each-group select="current-group()" group-starting-with="record[normalize-space(@property)]">			<condition>			  <property><xsl:value-of select="@property"/></property>			  <operator><xsl:value-of select="@operator"/></operator>			  <values>				<xsl:apply-templates select="current-group()"/>			  </values>			</condition>		  </xsl:for-each-group>		</subQuery>	  </xsl:for-each-group>	</defaultQuery>  </xsl:template>    <xsl:template match="data/record">	<value><xsl:value-of select="@value"/></value>  </xsl:template>  </xsl:stylesheet>

Please next time when you post code samples consider to mark them up properly as "code".

Link to comment
Share on other sites

thanks again martin...this xslt works perfectly when i checked with altova xml spy..but the version is 2.0The tool that i use only supports version="1.0".can u help in converting the same to version="1.0..Thanks a lot again for making my things simple

Link to comment
Share on other sites

Hi Martin,i tried with the below changes for the XSLT u gave ..but not able to do...it is giving me only the record that has serial number...pls help...thks in advance<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output indent="yes"/> <xsl:key name="k1" match="data/record[not(normalize-space(@property))]" use="generate-id(preceding-sibling::record[normalize-space(@property)][1])"/> <xsl:template match="data"> <defaultQuery> <xsl:apply-templates select="record[normalize-space(@slno)]" mode="group"/> </defaultQuery> </xsl:template> <xsl:template match="data/record" mode="group"> <subQuery> <xsl:apply-templates select="record[normalize-space(@property)]" mode="group"/> </subQuery> </xsl:template> <xsl:template match="data/record" mode="group"> <condition> <property><xsl:value-of select="@property"/></property> <operator><xsl:value-of select="@operator"/></operator> <values> <xsl:apply-templates select=". | key('k1', generate-id())"/> </values> </condition> </xsl:template> <xsl:template match="data/record"> <value><xsl:value-of select="@value"/></value> </xsl:template> </xsl:stylesheet>

Link to comment
Share on other sites

  • 2 weeks later...

hi martin,i am able to acheive below...pleas help me in doing the last step..i am running out of time...atleast please let me know whether i can get the below output or not?i am getting the below o/p:<?xml version="1.0"?><defaultQuery><subQuery><slno>1</slno></subQuery><subQuery><slno>2</slno></subQuery><condition><property>DISTRIBUTION</property><operator>=</operator><values><value>UNITED KINGDOM</value></values></condition><condition><property>BRAND OWNER</property><operator>Contains</operator><values><value>HOOK</value><value>500ML</value></values></condition><condition><property>DISTRIBUTION2</property><operator>=</operator><values><value>UNITED KINGDOM</value></values></condition><condition><property>BRAND OWNER2</property><operator>Contains</operator><values><value>HOOK1</value><value>500ML1</value></values></condition></defaultQuery>but i want it as follows:<?xml version="1.0"?><defaultQuery><subQuery slno=1><condition><property>DISTRIBUTION</property><operator>=</operator><values><value>UNITED KINGDOM</value></values></condition><condition><property>BRAND OWNER</property><operator>Contains</operator><values><value>HOOK</value><value>500ML</value></values></condition></subQuery><subQuery slno=2><condition><property>DISTRIBUTION2</property><operator>=</operator><values><value>UNITED KINGDOM</value></values></condition><condition><property>BRAND OWNER2</property><operator>Contains</operator><values><value>HOOK1</value><value>500ML1</value></values></condition></subQuery></defaultQuery>below is my xslt:<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output indent="yes"/> <xsl:key name="k1" match="data/record[not(normalize-space(@property))]" use="generate-id(preceding-sibling::record[normalize-space(@property)][1])"/> <xsl:template match="data"> <defaultQuery> <xsl:apply-templates select="record[normalize-space(@slno)]" mode="groupslno"/> <xsl:apply-templates select="record[normalize-space(@property)]" mode="groupproperty"/> </defaultQuery> </xsl:template> <xsl:template match="data/record" mode="groupslno"> <subQuery> <slno><xsl:value-of select="@slno"/></slno> </subQuery> </xsl:template> <xsl:template match="data/record" mode="groupproperty"> <condition> <property><xsl:value-of select="@property"/></property> <operator><xsl:value-of select="@operator"/></operator> <values> <xsl:apply-templates select=". | key('k1', generate-id())"/> </values> </condition> </xsl:template> <xsl:template match="data/record"> <value><xsl:value-of select="@value"/></value> </xsl:template> </xsl:stylesheet>please help....

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...