Discussion:
Xpath: What for self::* or preceding-sibling::*
(too old to reply)
Han
2004-04-26 08:00:48 UTC
Permalink
We know ancestor-or-self, descendant-or-self. But what if we want
preceding-sibling-or-self? No such thing. "|" doesn't work as I expect. e.g.

.|preceding-sibling::*[blahblah]
self::*|preceding-sibling::*[blahblah]
(self::*|preceding-sibling::*)[blahblah]

will not do. Currently I'm using,

$p/parent::*/*[count(preceding-sibling::*) >=
count($p2/preceding-sibling::*)]

It selects all the preceding-siblings and the context node starting from $p.
I guess more neat xpath exists.
Oleg Tkachenko [MVP]
2004-04-26 09:19:26 UTC
Permalink
Post by Han
We know ancestor-or-self, descendant-or-self. But what if we want
preceding-sibling-or-self? No such thing. "|" doesn't work as I expect. e.g.
.|preceding-sibling::*[blahblah]
Should work. Why do you think it doesn't work?
--
Oleg Tkachenko [XML MVP, XmlInsider]
http://blog.tkachenko.com
Han
2004-04-26 11:11:09 UTC
Permalink
Thanks for your commend, Oleg.

After your comment, I noticed the problem or difference comes only when I do
sum().

$p/. | preceding-sibling::* / @a1
parent::*/*[count(preceding-sibling::*) <=
count($p/preceding-sibling::*)]/@a1

Two xpaths may have same result when we select or do count(). However when I
do sum(),

sum($p/. | preceding-sibling::* / @a1)
sum($p/parent::*/*[count(preceding-sibling::*) <=
count($p/preceding-sibling::*)]/@a1)"

The results are different. How can I use the first xpath when I do sum()?
Help me. Here is an example xml+xslt.

<a>
<b a1='1'/>
<c a1='2'/>
<d/>
</a>

<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method='xml'
indent='yes' omit-xml-declaration='yes'/>

<xsl:template match="c">
<xsl:call-template name='t'>
<xsl:with-param name='p' select='.'/>
</xsl:call-template>
</xsl:template>

<xsl:template name='t'>
<xsl:param name='p'/>

<xsl:copy-of select='$p'/>

<c1>
<!--xsl:value-of select="
sum($p/. | preceding-sibling::* / @a1)"/-->
<xsl:value-of select="
sum($p/parent::*/*[count(preceding-sibling::*) &lt;=
count($p/preceding-sibling::*)]/@a1)"/>
</c1>

</xsl:template>

<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>

</xsl:stylesheet>
Post by Oleg Tkachenko [MVP]
Post by Han
We know ancestor-or-self, descendant-or-self. But what if we want
preceding-sibling-or-self? No such thing. "|" doesn't work as I expect. e.g.
.|preceding-sibling::*[blahblah]
Should work. Why do you think it doesn't work?
--
Oleg Tkachenko [XML MVP, XmlInsider]
http://blog.tkachenko.com
Han
2004-04-26 13:34:53 UTC
Permalink
Sorry the wrong pasting. I rewrite the earlier reply.

Thanks for your comment, Oleg.

After your comment, I noticed the problem or difference comes only when I do
sum().

$p/. | preceding-sibling::* / @a1
parent::*/*[count(preceding-sibling::*) &lt;= $p/preceding-sibling::*)]/@a1

Two xpaths may have same result when we select or do count(). However when I
do sum(),

sum($p/. | preceding-sibling::* / @a1)
sum($p/parent::*/*[count(preceding-sibling::*) &lt;=
$p/preceding-sibling::*)]/@a1)

The results are different. How can I use the first xpath when I do sum()?
Help me. Here is an example xml+xslt.

<a>
<b a1='1'/>
<c a1='2'/>
<d/>
</a>

<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method='xml'
indent='yes' omit-xml-declaration='yes'/>

<xsl:template match="c">
<xsl:call-template name='t'>
<xsl:with-param name='p' select='.'/>
</xsl:call-template>
</xsl:template>

<xsl:template name='t'>
<xsl:param name='p'/>

<xsl:copy-of select='$p'/>

<c1>
<!--xsl:value-of select="
sum($p/. | preceding-sibling::* / @a1)"/-->
<xsl:value-of select="
sum($p/parent::*/*[count(preceding-sibling::*) &lt;=
count($p/preceding-sibling::*)]/@a1)"/>
</c1>

</xsl:template>

<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>

</xsl:stylesheet>
Post by Han
Thanks for your commend, Oleg.
After your comment, I noticed the problem or difference comes only when I do
sum().
parent::*/*[count(preceding-sibling::*) &lt;=
Two xpaths may have same result when we select or do count(). However when I
do sum(),
sum($p/parent::*/*[count(preceding-sibling::*) &lt;=
The results are different. How can I use the first xpath when I do sum()?
Help me. Here is an example xml+xslt.
<a>
<b a1='1'/>
<c a1='2'/>
<d/>
</a>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method='xml'
indent='yes' omit-xml-declaration='yes'/>
<xsl:template match="c">
<xsl:call-template name='t'>
<xsl:with-param name='p' select='.'/>
</xsl:call-template>
</xsl:template>
<xsl:template name='t'>
<xsl:param name='p'/>
<xsl:copy-of select='$p'/>
<c1>
<!--xsl:value-of select="
<xsl:value-of select="
sum($p/parent::*/*[count(preceding-sibling::*) &lt;=
</c1>
</xsl:template>
<xsl:copy>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Post by Oleg Tkachenko [MVP]
Post by Han
We know ancestor-or-self, descendant-or-self. But what if we want
preceding-sibling-or-self? No such thing. "|" doesn't work as I
expect.
Post by Han
e.g.
Post by Oleg Tkachenko [MVP]
Post by Han
.|preceding-sibling::*[blahblah]
Should work. Why do you think it doesn't work?
--
Oleg Tkachenko [XML MVP, XmlInsider]
http://blog.tkachenko.com
Oleg Tkachenko [MVP]
2004-04-28 08:08:36 UTC
Permalink
Post by Han
After your comment, I noticed the problem or difference comes only when I do
sum().
Two xpaths may have same result when we select or do count(). However when I
do sum(),
Most likely it should be

sum($p/@a1 | preceding-sibling::*/@a1)
or even
sum(@a1 | preceding-sibling::*/@a1)
as context node is c element anyway.
--
Oleg Tkachenko [XML MVP, XmlInsider]
http://blog.tkachenko.com
Han
2004-04-28 07:49:45 UTC
Permalink
Thank you very much Oleg. I had also discovered,
Post by Oleg Tkachenko [MVP]
Post by Han
After your comment, I noticed the problem or difference comes only when I do
sum().
parent::*/*[count(preceding-sibling::*) &lt;=
Two xpaths may have same result when we select or do count(). However when I
do sum(),
Most likely it should be
or even
as context node is c element anyway.
--
Oleg Tkachenko [XML MVP, XmlInsider]
http://blog.tkachenko.com
Loading...