vsciw Posted February 20, 2011 Share Posted February 20, 2011 Hi.i have a bit of a problem with a file i'm trying to convert into xml. the file has the same format for each node but with different record types and i want to convert them into a tree using this record type. the input file is like this:<record> <type>A</type> <data>...</data></record><record> <type>B</type> <data>...</data></record><record> <type>C</type> <data>...</data></record><record> <type>C</type> <data>...</data></record><record> <type>C</type> <data>...</data></record><record> <type>B</type> <data>...</data></record><record> <type>C</type> <data>...</data></record><record> <type>C</type> <data>...</data></record>and i want the output like this (with obviously the data in the correct node):<A> <B> <C></C> <C></C> <C></C> </B> <B> <C></C> <C></C> </B>i've almost got it working using templates matching <record>, and inside the template check the type=a b or c. when i have a type=a, i apply the same record template but only select nodes where type=b, and similar when i have a type=b apply template selecting nodes where type=c. <xsl:template match="/"> <records> <xsl:apply-templates select="record[1]"/> </records> </xsl:template> <xsl:template match="record"> <xsl:element name="{type}"> <xsl:choose> <xsl:when test ="type='A'"> <xsl:apply-templates select="following-sibling::record_[type=B]"/> </xsl:when> <xsl:when test ="type='B'"> <xsl:apply-templates select="following-sibling::record_[type=C]"/> </xsl:when> </xsl:choose> </xsl:element> </xsl:template>the problem is that on the first type B, i'm getting all 5 type C output, when i only want the 1st 3 that are before the 2nd type B (if that makes sense!)can anyone help me? i though of using position but not sure how - maybe selecting type C where position > current type B and < next type B ????thanks. ian. Link to comment Share on other sites More sharing options...
JohnBampton Posted February 21, 2011 Share Posted February 21, 2011 Hi, this uses xslt 2.0 <?xml version="1.0" encoding="UTF-8"?><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" omit-xml-declaration="no" method="xml"></xsl:output> <xsl:template match="/"> <records> <A> <xsl:variable name="root" select="."></xsl:variable> <xsl:variable name="numberofb" select="count(//record[type='B'])"></xsl:variable> <xsl:for-each select="1 to $numberofb"> <B> <xsl:variable name="current" select="."></xsl:variable> <xsl:choose> <xsl:when test="$current != $numberofb"> <xsl:for-each select="for $T1 in ($root//record[type='B'])[$current], $T2 in ($root//record[type='B'])[$current + 1] return ($T1, $root//*[. >> $T1 and . << $T2])"> <xsl:if test="type='C'"> <C></C> </xsl:if> </xsl:for-each> </xsl:when> <xsl:when test="$current = $numberofb"> <xsl:for-each select="for $T1 in ($root//record[type='B'])[$current] return ($T1, $root//*[. >> $T1 ])"> <xsl:if test="type='C'"> <C></C> </xsl:if> </xsl:for-each> </xsl:when> </xsl:choose> </B> </xsl:for-each> </A> </records> </xsl:template></xsl:stylesheet> Regards, John Bampton. Link to comment Share on other sites More sharing options...
vsciw Posted February 22, 2011 Author Share Posted February 22, 2011 Hi.wasnt sure what was involved in deploying xslt v2, but managed to find this link using v1.0.http://www.webmasterworld.com/xml/3671431.htmi added levels to the input file, and modified the sample to use a level node not attribute and it appears to be working ok.ian. Hi, this uses xslt 2.0<?xml version="1.0" encoding="UTF-8"?><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" omit-xml-declaration="no" method="xml"></xsl:output> <xsl:template match="/"> <records> <A> <xsl:variable name="root" select="."></xsl:variable> <xsl:variable name="numberofb" select="count(//record[type='B'])"></xsl:variable> <xsl:for-each select="1 to $numberofb"> <B> <xsl:variable name="current" select="."></xsl:variable> <xsl:choose> <xsl:when test="$current != $numberofb"> <xsl:for-each select="for $T1 in ($root//record[type='B'])[$current], $T2 in ($root//record[type='B'])[$current + 1] return ($T1, $root//*[. >> $T1 and . << $T2])"> <xsl:if test="type='C'"> <C></C> </xsl:if> </xsl:for-each> </xsl:when> <xsl:when test="$current = $numberofb"> <xsl:for-each select="for $T1 in ($root//record[type='B'])[$current] return ($T1, $root//*[. >> $T1 ])"> <xsl:if test="type='C'"> <C></C> </xsl:if> </xsl:for-each> </xsl:when> </xsl:choose> </B> </xsl:for-each> </A> </records> </xsl:template></xsl:stylesheet> Regards, John Bampton. Link to comment Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.