Re: [xsl] position matching

Subject: Re: [xsl] position matching
From: "Vasu Chakkera" <vasucv@xxxxxxxxx>
Date: Fri, 28 Nov 2008 10:38:39 +0000
><mac:value-of  select="{/map/source[$position]}"/>
>changed to
><mac:value-of select="{../source[$pos]}"/>

Both would be the same if the map were the root element.
Vasu

2008/11/28 Ganesh Babu N <nbabuganesh@xxxxxxxxx>
>
> 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
>



--
Vasu Chakkera
Numerical Algorithms Group Ltd.
Oxford
www.vasucv.com

Current Thread