[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

Re: [xsl] position matching


Subject: Re: [xsl] position matching
From: "Ganesh Babu N" <nbabuganesh@xxxxxxxxx>
Date: Fri, 28 Nov 2008 11:35:44 +0530

Thank you very much Vasu and Michael for you valuable suggesting and
pointing out my mistakes.

the provided style sheet is working with small modification.

<mac:value-of  select="{/map/source[$position]}"/>
changed to
<mac:value-of select="{../source[$pos]}"/>

Regards,
Ganesh


On Thu, Nov 27, 2008 at 4:14 PM, Vasu Chakkera <vasucv@xxxxxxxxx> wrote:
> Ok here goes your errors in stylesheets..
>
>>  <xsl:for-each select="target[$pos > 1]">
>>                                                <mac:attribute name="substring-after({target[$pos]},'@')">
>>                                                        <mac:value-of  select="(preceding-sibling::source)[$pos]"/>
>>                                                        </mac:attribute>
>>                                                </xsl:for-each>
>
> Problem 1 :
> You are selecting the target > 1 so in the resulting nodeset, you will
> have 2nd target and the 3rd target ( in the order of your xml) //
>
> So you have lost the positioning of the input XML source , so you will
> never get the correct source value with your position, because the
> position() will give 1 for the 2nd target ( of your xml) and 2 for the
> third target (of your XML)..
>
> So for getting your numbering correct you muct allow all the targets
> in and possibly put an if condition to not process the first one.
>
>  <xsl:for-each select="target">
>
> Problem 2:
>   <mac:attribute name="substring-after({target[$pos]},'@')">
>
> Firstly, you have used the  Attribute Value Template wrongly ..
> so the above should be
>  <mac:attribute name="{substring-after(target[$pos],'@')}">
>  Secondly :
> Your for-each loops through target. So your current context is the
> target element.
> and your substring-after is looking for target element under the
> crrent context. so unless there was  target/target, you will never
> win.
>
> It should have been :
>
>   <mac:attribute name="{substring-after(.,'@')}">
>
> Problem 3:
>  <mac:value-of  select="(preceding-sibling::source)[$pos]"/>
>
> As mentioned in the problem 1: , Your use of position is wrong..
> because of your filter in the for-each that counts from the second
> target element. You will never get the correct corresponding source
> element.
>
> what you want is  better imagined, if you could use /map/source , to
> match the corresponding source ( coming from top to down)
>
> so define:
>
> <xsl:variable name = "position" select="position()"/>
>
> and then use
>
> <mac:value-of  select="{/map/source[$position]}"/>
>
>
>
> So here is the complete Stylesheet:
>
> <xsl:template match="map">
>                <xsl:if test="count(child::source) = count(child::target) and
>                not( count(child::*) = 2 )">
>                        <mac:template match="{source[1]}">
>                                <mac:element name="{target[1]}">
>                                        <xsl:for-each select="target">
>                                                <xsl:variable name = "position" select="position()"/>
>                                                <xsl:if test = "not(position() = 1)">
>                                                        <mac:attribute  name="{substring-after(.,'@')}">
>                                                                <mac:value-of  select="{/map/source[$position]}"/>
>                                                        </mac:attribute>
>                                                </xsl:if>
>                                        </xsl:for-each>
>                                        <mac:apply-templates select="@*|node()"/>
>                                </mac:element>
>                        </mac:template>
>                </xsl:if>
>        </xsl:template>
>
> The above produces:
> <mac:template match="article">
>        <mac:element name="article">
>                <mac:attribute name="article-type">
>                        <mac:value-of select="@docsubtype" />
>                </mac:attribute>
>                <mac:attribute name="dtd-version">
>                        <mac:value-of select="@version" />
>                </mac:attribute>
>                <mac:apply-templates select="@*|node()" />
>        </mac:element>
> </mac:template>
>
> HTH
>
> Vasu Chakkera.
>
> 2008/11/27 Ganesh Babu N <nbabuganesh@xxxxxxxxx>:
>> Hai
>>
>> Based on Michael points i have updated the XSL but I am not getting
>> any output. Please help me.
>> <xsl:template match="map">
>> <xsl:if test="count(child::source) = count(child::target) and
>> count(child::*) != 2">
>>                                <xsl:variable name="pos"><xsl:value-of
>> select="target[position()]"/></xsl:variable>
>>                                <mac:template match="{source[$pos]}">
>>                                        <mac:element name="{target[$pos]}">
>>                                                <xsl:for-each select="target[$pos > 1]">
>>                                                <mac:attribute name="substring-after({target[$pos]},'@')">
>>                                                        <mac:value-of
>> select="(preceding-sibling::source)[$pos]"/>
>>                                                        </mac:attribute>
>>                                                </xsl:for-each>
>>                                        <mac:apply-templates select="@*|node()"/>
>>                                        </mac:element>
>>                                </mac:template>
>>                        </xsl:if>
>> </xsl:template>
>>
>> Regards,
>> Ganesh
>>
>>
>> On Wed, Nov 26, 2008 at 4:31 PM, Michael Kay <mike@xxxxxxxxxxxx> wrote:
>>> Two obvious errors, excluding typos:
>>>
>>> (1) target[position() > 2] should be target[position() > 1]
>>>
>>> (2) preceding-sibling::source[position()] - you've forgotten that the
>>> context inside a predicate changes. You need to bind position() to a
>>> variable p outside the expression and then use
>>> preceding-sibling::source[$p]. Or in fact I suspect it should be
>>> (preceding-sibling::source)[$p] because you want them numbered in forwards
>>> rather than reverse order.
>>>
>>> Michael Kay
>>> http://www.saxonica.com/
>>>
>>>
>>>
>>>> -----Original Message-----
>>>> From: Ganesh Babu N [mailto:nbabuganesh@xxxxxxxxx]
>>>> Sent: 26 November 2008 10:52
>>>> To: XSL
>>>> Subject: [xsl] position matching
>>>>
>>>> Hai All,
>>>>
>>>> I am working on automatic XSLT generation project and here is
>>>> the mapping table.
>>>>
>>>> Here is my XML file:
>>>>  <map>
>>>>       <source>article</source>
>>>>       <source>@docsubtype</source>
>>>>       <source>@version</source>
>>>>       <target>article</target>
>>>>       <target>@article-type</target>
>>>>       <target>@dtd-version</target>
>>>>    </map>
>>>>
>>>> My stylesheet:
>>>>
>>>> <xsl:template match="map">
>>>> <xsl:if test="count(child::source) = count(child::target) and
>>>> count(child::*) != 2">
>>>> <mac:template match="{source[1]}">
>>>> <mac:element name="{target[1]}">
>>>> <xsl:for-each select="target[position() > 2"> <mac:attribute
>>>> name="substring-after({target},'@')"><mac:value-of
>>>> select="preceding-sibling::source[position()]"/></mac:attribute>
>>>> <xsl:for-each>
>>>> <mac:apply-templates select="@*|node()"/> </mac:element>
>>>> </mac:template> </xsl:if> </xsl:template>
>>>>
>>>> Expected Output:
>>>>
>>>> <xsl:template match="article>
>>>> <xsl:element name="article">
>>>> <xsl:attribute name="article-type"><xsl:value-of
>>>> select="@docsubtype"></xsl:attribute>
>>>> <xsl:attribute name="@dtd-version"><xsl:value-of
>>>> select="@version"></xsl:attribute>
>>>> </xsl:element>
>>>> <xsl:template>
>>>>
>>>>
>>>> I am not getting the desired result. Please let me know where
>>>> I am going wrong.
>>>>
>>>> Regards,
>>>> Ganesh
>>
>>
>
>
>
> --
> Vasu Chakkera
> Numerical Algorithms Group Ltd.
> Oxford
> www.vasucv.com


Current Thread
Keywords