XPathの//item[1]とdescendant-or-self::item[1]の違い
非常に基本的なことなのでしょうけれども掲題の違いがわかりません.例えば次のようなXMLがあったとします.
<?xml version="1.0" encoding="UTF-8"?>
<root>
<item attr1="val1" attr2="val2">
<item attr3="val3">
<item attr4="val4">
<item attr5="val5"/>
</item>
</item>
</item>
</root>
これに対して次のようなスタイルシートを適用すると
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:output indent="yes"/>
<xsl:template match="/">
<root>
<p1-1>
<xsl:copy-of select="//item"/>
</p1-1>
<p1-2>
<xsl:copy-of select="descendant-or-self::item"/>
</p1-2>
</root>
</xsl:template>
</xsl:stylesheet>
p1-1とp1-2には同じ次の内容のノードが選択されます.
<item attr1="val1" attr2="val2">
<item attr3="val3">
<item attr4="val4">
<item attr5="val5"/>
</item>
</item>
</item>
<item attr3="val3">
<item attr4="val4">
<item attr5="val5"/>
</item>
</item>
<item attr4="val4">
<item attr5="val5"/>
</item>
<item attr5="val5"/>
ところがこれを
<xsl:template match="/">
<root>
<p1-1>
<xsl:copy-of select="//item[1]"/>
</p1-1>
<p1-2>
<xsl:copy-of select="descendant-or-self::item[1]"/>
</p1-2>
</root>
</xsl:template>
と変えると
<?xml version="1.0" encoding="UTF-8"?>
<root>
<p1-1>
<item attr1="val1" attr2="val2">
<item attr3="val3">
<item attr4="val4">
<item attr5="val5"/>
</item>
</item>
</item>
<item attr3="val3">
<item attr4="val4">
<item attr5="val5"/>
</item>
</item>
<item attr4="val4">
<item attr5="val5"/>
</item>
<item attr5="val5"/>
</p1-1>
<p1-2>
<item attr1="val1" attr2="val2">
<item attr3="val3">
<item attr4="val4">
<item attr5="val5"/>
</item>
</item>
</item>
</p1-2>
</root>
という結果となります.predicate(述語)の[1]は異なる結果をもたらします.
XPathの仕様によれば簡略記述の//item[1]は(fn:root(self::node()) treat as document-node())/descendant-or-self::node()/child::item[1]に等しくなります.
A "//" at the beginning of a path expression is an abbreviation for the initial steps (fn:root(self::node()) treat as document-node())/descendant-or-self::node()/ (however, "//" by itself is not a valid path expression [err:XPST0003].)
すこしややこしいですが、簡単に言えばドキュメントノードの位置から見てdescendant-or-self::node()/child::item[1]とdescendant-or-self::item[1]はどう違うのか?
ということになるでしょうか?なぜ両者が異なる結果となるのかがよくわかりません.
説明いただける方おられましたらよろしくお願いいたします.
[追記]
ちなみに仕様には違う結果になると書いてあります.
Note:The path expression //para[1] does not mean the same as the path expression /descendant::para[1]. The latter selects the first descendant para element; the former selects all descendant para elements that are the first para children of their respective parents.