Reputation: 2938
My XML before applying xslt looks like this:
<vehicle>
<driver repeatingtype="list">
<data repeatingindex="1">
<name>driver1</name>
<age>25</age>
</data>
<data repeatingindex="2">
<name>def</name>
<age>25</age>
</data>
<data repeatingindex="3">
<name>ghi</name>
<age>25</age>
</data>
</driver>
</vehicle>
I want to write an xslt which which gives me the xml in the following format -
<vehicle>
<maindriver> [Comment: This always has the first element(1) in the driver list]
<name>driver1</name>
<age>25</age>
</maindriver>
<additionaldrivers>
<name>def</name>
<age>25</age>
<name>ghi</name>
<age>25</age>
</additionaldrives>
</vehicle>
How do i write the xslt to pick up the first element in the page list and put it in the main driver tag and the rest of the elements in the additional driver tag. I am looking for something which does not repeat the code for the template. I have written the following xslt but has duplicate code for the driver tag -
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:template match="vehicle">
<maindriver>
<xsl:apply-templates select="driver/data[1]"/>
</maindriver>
<additionaldrivers>
<xsl:apply-templates select="driver"/>
</additionaldrivers>
</xsl:template>
<xsl:template match="driver/data[1]">
-----Code to capture the details----
</xsl:template>
<xsl:template match="driver">
<xsl:choose>
<xsl:when test="'$data -gt 1'">
<xsl:for-each select="rowdata">
---- Repeating Code as of the main driver----
</xsl:for-each>
</xsl:when>
</xsl:choose>
</xsl:template>
Upvotes: 0
Views: 2128
Reputation: 3714
What about this?
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="vehicle">
<xsl:copy>
<maindriver>
<xsl:apply-templates select="driver/data[1]/*" mode="data"/>
</maindriver>
<additionaldrivers>
<xsl:for-each select="driver/data">
<xsl:if test="position()>1">
<xsl:apply-templates select="*" mode="data"/>
</xsl:if>
</xsl:for-each>
</additionaldrivers>
</xsl:copy>
</xsl:template>
<xsl:template match="*" mode="data">
<xsl:copy>
<xsl:apply-templates select="*" mode="data"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
In your case a solution without extra modes will also work
another way if you need a additional driver elem ...
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="vehicle">
<xsl:copy>
<maindriver>
<xsl:apply-templates select="driver/data[1]/*"/>
</maindriver>
<additionaldrivers>
<xsl:apply-templates select="driver/data" mode="additional"/>
</additionaldrivers>
</xsl:copy>
</xsl:template>
<xsl:template match="data" mode="additional">
<xsl:if test="position() > 1">
<driver>
<xsl:apply-templates select="*"/>
</driver>
</xsl:if>
</xsl:template>
<xsl:template match="*">
<xsl:copy>
<xsl:apply-templates select="*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Upvotes: 1
Reputation: 2146
First, you should correct all the syntax errors in your documents:
Tag mismatch in the input:
<name>ghi</abc>
Stylesheet declaration:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
Missing closing tag of the vehicle
template:
</xsl:template>
Incorrect closing tag of the maindriver
tag:
<maindriver>
<xsl:apply-templates select="driver/data[1]"/>
</maindriver>
Then you can use position() gt; 1
in the select
for your additional drivers:
<xsl:apply-templates select="driver/data[ position() > 1 ]"/>
All together:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" xmlns:xalan="http://xml.apache.org/xslt" doctype-public="XSLT-compat" omit-xml-declaration="yes" encoding="UTF-8" />
<xsl:template match="/">
<vehicle>
<xsl:apply-templates select="vehicle"/>
</vehicle>
</xsl:template>
<xsl:template match="vehicle">
<maindriver>
<xsl:apply-templates select="driver/data[1]"/>
</maindriver>
<additionaldrivers>
<xsl:apply-templates select="driver/data[ position() > 1 ]"/>
</additionaldrivers>
</xsl:template>
<xsl:template match="driver/data">
<xsl:copy-of select="*"/>
</xsl:template>
</xsl:stylesheet>
Upvotes: 1