[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message] Re: (re-)calculating attribute values
Hello Christian, it's important to know the difference between the input-tree and the output-tree. You can't access the calculated values after the first gap, if you only write them to the output-tree. The best solution in my eyes is to use a recursive template, which processes node by node: <xsl:template match="root"> <!-- copy all As and Bs before any gap, because they must not be processed recursively --> <xsl:variable name="before-gap" select="(A|B)[not(preceding-sibling::C)]"/> <xsl:copy-of select="$before-gap"/> <!-- apply templates on the first A or B after a gap --> <xsl:apply-templates select="(A|B)[preceding-sibling::C][1]"> <xsl:with-param name="start" select="$before-gap[last()]/@end + 1"/> </xsl:apply-templates> </xsl:template> <xsl:template match="A|B"> <xsl:param name="start" select="1"/> <xsl:variable name="end" select="$start + (@end - @start)"/> <xsl:copy> <xsl:attribute name="start"><xsl:value-of select="$start"/></xsl:attribute> <xsl:attribute name="end"><xsl:value-of select="$end"/></xsl:attribute> <xsl:apply-templates/> </xsl:copy> <xsl:apply-templates select="following-sibling::*[self::A or self::B][1]"> <xsl:with-param name="start" select="$end + 1"/> </xsl:apply-templates> </xsl:template> You have got already a solution with for-each from Michael Kay. But there every preceding node must be accessed and totalized again. According to your file size this will make no difference, but when it's big you will see the time differences. Furthermore you can shorten the code in the first template if you process the first nodes in front of the frst C too, i.e. calculating their @start and @end too, even it's not needed, because you know already the values: <xsl:template match="root"> <xsl:apply-templates select="(A|B)[1]"> <xsl:with-param name="start" select="(A|B)[1]/@start"/> </xsl:apply-templates> </xsl:template> Regards, Joerg > hello *.*, > following xml-file: > > <A start="20" end="28">Text1</A> > <B start="29" end="35">Text2</B> > <C start="36" end="39">Text3</C> > <C start="40" end="44">Text4</C> > <A start="45" end="51">Text5</A> > <C start="52" end="58">Text6</C> > <B start="59" end="69">Text7</B> > ... > > i want to write a xslt file which removes all <C> elements (no problem) and > recalculates start and end values by filling up the gaps. and here i have > the problem: in the first case it is possible to fill up the gab between the > first <B> and second <A>: > > 1: <A start="20" end="28">Text1</A> > 2: <B start="29" end="35">Text2</B> > 3: <!-- removed <C> element(s) --> > 4: <A start="36" end="42">Text5</A> > 5: <!-- removed <C> element(s) --> > 6: <B start="52" end="62">Text7</B> (problem!!!) > > The problem arises at the second gap (line 6). the gap is calculated by > using end value of second <A> and start value of last <B> (59-51=8) and not > by using already recalculated values in previous step (59-42=17). > > what's going wrong here? has anyone a hint or maybe a solution for me? > > any help would be appreciated! > > regards > christian XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
|
PURCHASE STYLUS STUDIO ONLINE TODAY!Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced! Download The World's Best XML IDE!Accelerate XML development with our award-winning XML IDE - Download a free trial today! Subscribe in XML format
|