Subject: Re: XPath problem with getting all ancestors
From: Jostein Austvik Jacobsen <josteinaj@xxxxxxxxx>
Date: Fri, 23 Oct 2009 14:12:42 +0200
|
Ah, I guess <xsl:copy-of select="content/node()"/> is the "problem"
that makes para my new root then?
So how would I modify my note template to do what I want?
-Jostein
2009/10/23 Vyacheslav Sedov <vyacheslav.sedov@xxxxxxxxx>:
> it is ok - you copy whole node - not reference so this stats refer to
> new constructed node
>
> On Fri, Oct 23, 2009 at 4:03 PM, Jostein Austvik Jacobsen
> <josteinaj@xxxxxxxxx> wrote:
>> Ok, I've stripped it down a fair bit. When I run this:
>>
>>
>> <?xml version="1.0" encoding="utf-8"?>
>> <document>
>> <article>
>> <meta>
>> <title>Title</title>
>> </meta>
>> <content>
>> <para>
>> <note id="1">text</note>
>> </para>
>> </content>
>> </article>
>> </document>
>>
>>
>> through this:
>>
>>
>> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>> version="2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema"
>> xmlns:mf="http://example.com/2009/mf" exclude-result-prefixes="xs mf">
>>
>> <xsl:template match="document">
>> <document>
>> <meta/>
>> <content>
>> <xsl:for-each select="article">
>> <xsl:sort select="(.//@page)[1]"/>
>> <xsl:apply-templates
select="article"/>
>> </xsl:for-each>
>> <xsl:apply-templates/>
>> </content>
>> </document>
>> </xsl:template>
>>
>> <xsl:template match="article">
>> <xsl:variable name="v1">
>> <xsl:copy-of select="content/node()"/>
>> </xsl:variable>
>> <xsl:sequence select="mf:group($v1/node())"/>
>> </xsl:template>
>> <xsl:function name="mf:group" as="node()*">
>> <xsl:param name="nodes" as="node()*"/>
>> <xsl:for-each-group select="$nodes"
group-starting-with="foo">
>> <xsl:apply-templates/>
>> </xsl:for-each-group>
>> </xsl:function>
>>
>> <xsl:template match="note">
>> The note at /article/content/para/note reads:
>> ancestors="<xsl:value-of select="count(ancestor::*)"/>"
>> preceding="<xsl:value-of select="count(preceding::*)"/>"
>> contentNum="<xsl:value-of
select="count(preceding::content)"/>"
>> numberTest="<xsl:number level="any" count="content"/>"
>> </xsl:template>
>>
>> </xsl:stylesheet>
>>
>>
>> I get this:
>>
>>
>> <?xml version="1.0" encoding="UTF-8"?>
>> <document>
>> <meta/>
>> <content>
>> The note at /article/content/para/note reads:
>> ancestors="1"
>> preceding="0"
>> contentNum="0"
>> numberTest=""
>> </content>
>> </document>
>>
>>
>> In this case I would expect:
>> ancestors="3" (para,content,article)
>> preceding="2" (meta,title)
>>
>> But I guess I'm applying the template in a wrong way?
>>
>> Regards
>> Jostein
>>
>> 2009/10/23 Jostein Austvik Jacobsen <josteinaj@xxxxxxxxx>:
>>> David/Syd: I tried replacing the value-of with <xsl:number level="any"
>>> count="content"/>, but it returned nothing. I'm sure I'm using it
>>> wrong though so I'll have myself a read on xsl:number.
>>> Syd: Sorry about the misplaced match. I tried it myself now and
>>> actually got the same as you.
>>> Syd/Michael: I'll try to strip down my stylesheet to localize the
>>> problem further, then I'll post it back here.
>>>
>>> Thanks
>>> Jostein
>>>
>>> 2009/10/23 Michael Kay <mike@xxxxxxxxxxxx>:
>>>>
>>>> My guess (and it's a completely wild one) is that you aren't applying
>>>> templates to the note element in the source tree as you have shown it,
but
>>>> to a copy of the note element in some smaller tree, probably a tree
rooted
>>>> at the para element.
>>>>
>>>> To confirm that we would need to see more of the stylesheet. Or, within
the
>>>> match="note" template, do
>>>>
>>>> <xsl:message><xsl:copy-of select="/"/></xsl:message>
>>>>
>>>> to see what tree you are processing at the time.
>>>>
>>>> Regards,
>>>>
>>>> Michael Kay
>>>> http://www.saxonica.com/
>>>> http://twitter.com/michaelhkay
>>>>
>>>>> -----Original Message-----
>>>>> From: Jostein Austvik Jacobsen [mailto:josteinaj@xxxxxxxxx]
>>>>> Sent: 23 October 2009 11:27
>>>>> To: xsl-list
>>>>> Subject: XPath problem with getting all ancestors
>>>>>
>>>>> I've got a document like this:
>>>>>
>>>>> <?xml version="1.0" encoding="utf-8"?>
>>>>> <document>
>>>>> <article>
>>>>> <meta>
>>>>> <title>Title</title>
>>>>> </meta>
>>>>> <content>
>>>>> <headline>Headline</headline>
>>>>> <para>
>>>>> <note id="1">text</note>
>>>>> </para>
>>>>> </content>
>>>>> </article>
>>>>> </document>
>>>>>
>>>>> And in a template for the note tags I'm trying to use the
>>>>> ancestor axis to get the list [ para , content , article ].
>>>>> However, I only seem to get [ para ] with ancestor::* and [ para , ""
>>>>> ] with ancestor::node().
>>>>> When I test it like this:
>>>>>
>>>>> <xsl:template match="note">
>>>>> ancestors="<xsl:value-of select="count(ancestor::*)"/>"
>>>>> preceding="<xsl:value-of select="count(preceding::*)"/>"
>>>>> contentNum="<xsl:value-of
>>>>> select="count(preceding::content)"/>"
>>>>> </xsl:template match>
>>>>>
>>>>> ...I get ancestors="1", preceding="2" and contentNum="0" as output.
>>>>>
>>>>> What I actually need to do is to count the number of content
>>>>> nodes preceding the current note (relevant for the input XML
>>>>> note numbering scheme). I did so earlier in the document (for
>>>>> referencing the actual
>>>>> notes) when matching document like this:
>>>>>
>>>>> <xsl:template match="document">
>>>>> (...)
>>>>> <xsl:for-each select="//note">
>>>>> <note>
>>>>> <xsl:attribute name="id"><xsl:value-of
>>>>> select="count(ancestor::content/preceding::content)"/></xsl:attribute>
>>>>> <p><xsl:apply-templates/></p>
>>>>> </note>
>>>>> </xsl:for-each>
>>>>> (...)
>>>>> </xsl:template>
>>>>>
>>>>> So here I get access to all of the notes ancestors. In
>>>>> retrospect I could probably have used
>>>>> select="count(preceding::content)" instead, but still...
>>>>>
>>>>> How come that I cannot access the notes ancestors from my
>>>>> note template?
>>>>>
>>>>> Regards
>>>>> Jostein
|