|
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 |