xml - Recursion and TreeNode xslt -
i newly introdused xslt, doing kind of small tasks familiarise myself xslt. stuck in problem not solve in transforming xml file one. scenario: input xml file contains nodes, each 1 pair of son , father tags indicates name of current node tag , , name of father node tag < father >. trying generate tree of node, first node 1 has no father (i created manually name 0 , level in tree 1), looking nodes have father tag equals (0) first step, in input file (1 , 4), here create new node node (0) holds name (1) , has level in tree equals (2) go , nodes have father tag equals (1) , on, when reach point no more children (1), create node name (4) , has same level in tree node name (1) continue looking nodes have father tag equals (4) , on. have xml:
<typedpolling xmlns="http://schemas.microsoft.com/sql/2008/05/typedpolling"> <typedpolling0> <typedpolling0> <son>1</son> <father>0</father> </typedpolling0> <typedpolling0> <son>2</son> <father>1</father> </typedpolling0> <typedpolling0> <son>3</son> <father>0</father> </typedpolling0> <typedpolling0> <son>4</son> <father>3</father> </typedpolling0> </typedpolling0> </typedpolling>
the previous xml file should transformed xml file:
<ns0:treenode> <ns0:node>0</ns0:node> <ns0:levelintree>1</ns0:levelintree> <ns0:treenode> <ns0:node>1</ns0:node> <ns0:levelintree>2</ns0:levelintree> <ns0:treenode> <ns0:node>2</ns0:node> <ns0:levelintree>3</ns0:levelintree> </ns0:treenode> </ns0:treenode> <ns0:treenode> <ns0:node>3</ns0:node> <ns0:levelintree>2</ns0:levelintree> <treenode> <ns0:node>4</ns0:node> <ns0:levelintree>3</ns0:levelintree> </treenode> </treenode> </treenode>
the code write transform input (i used key element sons have specified father name):
<?xml version="1.0" encoding="utf-16"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:var="http://schemas.microsoft.com/biztalk/2003/var" xmlns:s0="http://schemas.microsoft.com/sql/2008/05/typedpolling" xmlns:ns0="http://no.aditro.schemas.organization.organizationtrees" xmlns:usercsharp="http://schemas.microsoft.com/biztalk/2003/usercsharp" exclude-result-prefixes="msxsl var s0 usercsharp"> <xsl:output omit-xml-declaration="yes" method="xml" indent="yes" version="1.0" /> <xsl:key name="keyitemfather" match="/s0:typedpolling/s0:typedpolling0/s0:typedpolling0" use="@father" /> <xsl:template match="/"> <xsl:variable name="son" select="0" /> <xsl:variable name="level" select="1" /> <xsl:apply-templates mode="newnode" select="/s0:typedpolling/s0:typedpolling0"> <xsl:with-param name="level" select="$level" /> </xsl:apply-templates> </xsl:template> <xsl:template name="newtreenode" match="/s0:typedpolling/s0:typedpolling0/s0:typedpolling0" mode="newnode"> <xsl:param name="son" /> <xsl:param name="level" /> <ns0:treenode> <ns0:node> <xsl:value-of select="$son" /> </ns0:node> <ns0:levelintree> <xsl:value-of select="$level" /> </ns0:levelintree> <xsl:apply-templates select="key('keyitemfather', $son)" mode="newnode"> <xsl:with-param name="level" select="$level+1" /> </xsl:apply-templates> </ns0:treenode> </xsl:template> </xsl:stylesheet>
the problem got during recursion wrong happens recursion keeps going endlessly , <ns0:node></ns0:node>
stays empty (it should example <ns0:node>3</ns0:node>
). can't find mistake! :(
it looks me if you're pretty close: design approach right. there errors in things haven't shown us, namespace declarations - it's useful show complete runnable stylesheet, can try ourselves , use our favourite debugging tools, without having fill in bits left out.
the thing find confusing source data starts 1 typedpolling start tag followed 3 typedpolling0 start tags. first 2 of these start tags have no corresponding end tag. assuming left out, father
elements 4 levels deep. xsl:key
declaration wrong on 2 counts: firstly matches father
attributes rather elements (use="@father"
), , secondly has few ancestor levels. note don't need specify full path here, quite enough say
<xsl:key name="keyitemfather" match="s0:typedpolling0" use="father" />
the other thing notice template rule has 2 parameters (in both calls) supplying one. in fact, don't need $son
parameter, because can information accessing child::son
context node.
Comments
Post a Comment