Subject: [xsl] ReqursivelySplittingNode_Set From: mankar@xxxxxxxxxxxxxxx Date: Sun, 8 Aug 2004 18:30:39 +0300 |
Hallo, I need to split the ORDINATES_ITEM node set of the following source xml into three different node sets based on the positions of the ORDINATE_ITEM elements. So far i have come up with the xslt code that does this, considering the source xml to be static.The problem is that it is not, because it is generated dynamically each time. The splitting positions are extracted from the number content of each ELEM_INFO_ITEM[position() mod 3 = 1] which are for this particular example 1, 3 and 8.Based on these values which will serve as splitting positions for the ORDINATES_ITEM node set, i would like to select ORDINATE_ITEM elements from position 1 to position 2 in a node-set and then select ORDINATE_ITEM elements from position 3 to position 7 in another node-set and finally select ORDINATE_ITEM elements from position 8 to the last position in another node-set. source xml <?xml version="1.0" encoding="ISO-8859-7"?> <ROWSET> <ROW num="1"> <SHAPE> <ELEM_INFO> <ELEM_INFO_ITEM>1</ELEM_INFO_ITEM> <ELEM_INFO_ITEM>1003</ELEM_INFO_ITEM> <ELEM_INFO_ITEM>50</ELEM_INFO_ITEM> <ELEM_INFO_ITEM>3</ELEM_INFO_ITEM> <ELEM_INFO_ITEM>2003</ELEM_INFO_ITEM> <ELEM_INFO_ITEM>50</ELEM_INFO_ITEM> <ELEM_INFO_ITEM>8</ELEM_INFO_ITEM> <ELEM_INFO_ITEM>2003</ELEM_INFO_ITEM> <ELEM_INFO_ITEM>50</ELEM_INFO_ITEM> </ELEM_INFO> <ORDINATES> <ORDINATES_ITEM>52</ORDINATES_ITEM> <ORDINATES_ITEM>45</ORDINATES_ITEM> <ORDINATES_ITEM>54</ORDINATES_ITEM> <ORDINATES_ITEM>57</ORDINATES_ITEM> <ORDINATES_ITEM>76</ORDINATES_ITEM> <ORDINATES_ITEM>78</ORDINATES_ITEM> <ORDINATES_ITEM>56</ORDINATES_ITEM> <ORDINATES_ITEM>23</ORDINATES_ITEM> <ORDINATES_ITEM>32</ORDINATES_ITEM> </ORDINATES> </SHAPE> </ROW> </ROWSET> The xslt code i 've come up with so far, produces the desired output for this particular source xml! <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output indent="yes"/> <xsl:template match="/"> <PolygonSet> <xsl:for-each select="ROWSET/ROW"> <polygon> <exterior> <xsl:for-each select="SHAPE/ORDINATES/ORDINATES_ITEM"> <xsl:choose> <xsl:when test="position() < ancestor::SHAPE/ELEM_INFO/ELEM_INFO_ITEM[position() mod 3=1][2]"> <xsl:value-of select="."/> <xsl:text> </xsl:text> </xsl:when> </xsl:choose> </xsl:for-each> </exterior> <interior> <xsl:for-each select="SHAPE/ORDINATES/ORDINATES_ITEM"> <xsl:choose> <xsl:when test="(position() >= ancestor::SHAPE/ELEM_INFO/ELEM_INFO_ITEM[position() mod 3=1][2]) and (position() < ancestor::SHAPE/ELEM_INFO/ELEM_INFO_ITEM[position() mod 3=1][3])"> <xsl:value-of select="."/> <xsl:text> </xsl:text> </xsl:when> </xsl:choose> </xsl:for-each> </interior> <interior> <xsl:for-each select="SHAPE/ORDINATES/ORDINATES_ITEM"> <xsl:choose> <xsl:when test="position() >= ancestor::SHAPE/ELEM_INFO/ELEM_INFO_ITEM[position() mod 3=1][3] "> <xsl:value-of select="."/> <xsl:text> </xsl:text> </xsl:when> </xsl:choose> </xsl:for-each> </interior> </polygon> </xsl:for-each> </PolygonSet> </xsl:template> </xsl:stylesheet> As you can see i am selecting the content of ORDINATE_ITEM elements with positions position() <ELEM_INFO_ITEM[position() mod 3 =1][2] which is number 3 in this particular example as string content of an exterior element, the content of ORDINATE_ITEM elements with positions 3=<position()<8 as string content of an interior element and the content of ORDINATE_ITEM elements with positions 8=<position() as string content of another exterior element. <?xml version="1.0" encoding="UTF-16"?> <PolygonSet> <polygon> <exterior>52 45 </exterior> <interior>54 57 76 78 56 </interior> <interior>23 32 </interior> </polygon> </PolygonSet> The problem is that the source xml is generated dynamically.This means that i don't know from the first place the exact number of splitting positions which is determined by the ELEM_INFO_ITEM[position() mod 3 = 1].This source xml has exactly nine ELEM_INFO_ITEM elements, while another may have 6 or 12 etch.The sure thing is that every source will contain six ELEM_INFO_ITEM elements or more and always the total number will be multiple of three. If the source xml for example, had 12 ELEM_INFO_ITEM elements, then i would have 4 splitting positions and the desired output should contain one exterior element and three interior elements.If i have a source with six ELEM_INFO_ITEM elements, then the output should have one exterior plus one interior elements. So, for each source i want to create exactly one exterior element which will contain all ORDINATE_ITEM element's content that their position is less than ELEM_INFO_ITEM[position() mod 3 =1][2] and as many interior elements as the ELEM_INFO_ITEM[position() mod3=1] are, minus 1. I already handle the first issue in my xsl with : <exterior> <xsl:for-each select="SHAPE/ORDINATES/ORDINATES_ITEM"> <xsl:choose> <xsl:when test="position() < ancestor::SHAPE/ELEM_INFO/ELEM_INFO_ITEM[position() mod 3=1][2]"> <xsl:value-of select="."/> <xsl:text> </xsl:text> </xsl:when> </xsl:choose> </xsl:for-each> </exterior> I could also handle the automatic creation of as many interior elements as the ELEM_INFO_ITEM[position() mod3=1] are, minus 1, by incorporating in my code something like: <xsl:for-each select="SHAPE/ELEM_INFO/ELEM_INFO_ITEM[position()mod3=1][position() >1]"> <interior>...</interior> </xsl:for-each> My big problem is how to recursively apply the relevant ORDINATES_ITEM element's content to each interior. I mean the first interior (because there always be at least one interior) should contain ORDINATES_ITEM content whose position is always greater than or equal to ELEM_INFO_ITEM[position() mod 3=1][2]and less than ELEM_INFO_ITEM[position() mod 3=1][3], if there is such position. Otherwise it should just contain ORDINATES_ITEM content whose position is always greater than or equal to ELEM_INFO_ITEM[position() mod 3=1][2]. Similarly the second interior element, if one exists, should contain ORDINATES_ITEM content whose position is always greater than or equal to ELEM_INFO_ITEM[position() mod 3=1][3] and less than ELEM_INFO_ITEM[position() mod 3=1][4], if there is such position etc. And the last interior element should exactly contain ORDINATES_ITEM content whose position is always greater than or equal to ELEM_INFO_ITEM[position() mod 3=1][last()]. How can i recursively apply the relevant ORDINATE_ITEM contents to the each interior element? Regards Manousos Athens
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] regexs, grouping (?) and , David Carlisle | Thread | [xsl] Count Words, Karl J. Stubsjoen |
Re: [xsl] regexs, grouping (?) and , Bruce D'Arcus | Date | [xsl] Count Words, Karl J. Stubsjoen |
Month |