Subject: Re: [xsl] how do you count based on the number of preceding attributes? From: "Tony Zanella" <tony.zanella@xxxxxxxxx> Date: Fri, 6 Jun 2008 22:07:32 -0400 |
Dear Dr. Kay and Readers, Implementing the changes suggested below as follows, on this markup: <?xml version="1.0" encoding="UTF-8"?> <root> <div0 type="heading" id="abc.div.1.2.3"> <div1/><div1 type="article" id="abc.div.1.2.6"> <div2 type="subsection" id="abc.div.1.2.1"/> <pb n="1" id="abc.1.2.2"/> </div1> </div0> </root> With the sylesheet now reading: <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="@id[contains(.,'div')]"> <xsl:variable name="test_value" select="string(count(preceding::*[contains(@id, 'div')]))"/> <xsl:attribute name="id" select="replace(., '[0-9]+$', $test_value)"/> </xsl:template> </xsl:stylesheet> I get the output: <?xml version="1.0" encoding="UTF-8"?><root> <div0 type="heading" id="abc.div.1.2.0"> <div1/><div1 type="article" id="abc.div.1.2.0"> <div2 type="subsection" id="abc.div.1.2.0"/> <pb n="1" id="abc.1.2.2"/> </div1> </div0> </root> The output I want is: <?xml version="1.0" encoding="UTF-8"?><root> <div0 type="heading" id="abc.div.1.2.1"> <div1/><div1 type="article" id="abc.div.1.2.2"> <div2 type="subsection" id="abc.div.1.2.3"/> <pb n="1" id="abc.1.2.2"/> </div1> </div0> </root> Any further suggestions? (If it helps to hear: the test case represents a file where the last integers in the div @id attributes are misnumbered, and the goal of the stylesheet is to number them sequentially...the pb element has an @id attribute, but it's not my concern here...). Thanks for your help and patience with my slow learning process, Tony Zanella On Fri, Jun 6, 2008 at 4:47 PM, Michael Kay <mike@xxxxxxxxxxxx> wrote: >> Using xsl processor: Saxon 8B, here's my test data: >> >> <?xml version="1.0" encoding="UTF-8"?> >> <root> >> <div0 type="heading" id="abc.div.1.2.3"> >> <div1 type="article" id="abc.div.1.2.6"> >> <div2 type="subsection" id="abc.div.1.2.1"/> >> <pb n="1" id="abc.1.2.2"/> >> <div2 type="subsection" id="abc.div.1.2.64"/> >> </div1> >> </div0> >> </root> >> >> Here's the stylesheet I'm working on: >> > [identity template]+ >> >> <xsl:template match="*/@id[contains(.,'div')]"> > > The "*/" adds nothing (well, it says "only match id attributes if they have > an element as a parent"). You can drop it. >> >> <xsl:variable name="substring" >> select="substring-after(substring-after(substring-after(substr >> ing-after(.,'.'),'.'),'.'),'.')"/> > > You don't seem to use this variable and I don't think you need it. > >> <xsl:variable name="test_value"><xsl:value-of >> select="count(preceding::node())"/></xsl:variable> > > NEVER write variables like this. It should be > > <xsl:variable name="test_value" select="string(count(preceding::node()))"/> > > You don't want a document node containing a text node; you want the integer, > converted to a string. > >> I want the value of $test_value to be, for example, 1 if the @id > containing the string 'div' is the first @id, 2 if it is the second, and so > on. > > You haven't made it clear whether you want to count all @id attributes, or > only those that contain 'div'. In the first case it's > count(preceding::*[@id]), in the second it's > count(preceding::*[contains(@id, 'div')]). > > Alternatively, use <xsl:number level="any" count="*[@id]"/> > >> <xsl:attribute name="id" >> select="concat(replace(.,'([a-z]{3})\.div\.([0-9]+)\.([0-9]+)\ >> .([0-9]+)','$1.div.$2.$3.'),$test_value)"/> > > The seems very cumbersome. To replace the last number in the string, use > > replace(., '[0-9]+$', $test_value) > > Michael Kay > http://www.saxonica.com/
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
RE: [xsl] how do you count based on, Michael Kay | Thread | Re: [xsl] how do you count based on, Tony Zanella |
Re: [xsl] self axis vs ., Robert Koberg | Date | Re: [xsl] self axis vs ., Andrew Welch |
Month |