実現したいこと
XSLT 2.0以上で、node()* と node()* を比較する関数を作って、結果を真偽値(xs:boolean)で得たいです.
発生している問題・分からないこと
単独のnode()の比較なら以下のようにできます.
xml
1<!--"~"は適当なXPath式を示します--> 2<xsl:variable name="node1" as="node()" select="~"/> 3<xsl:variable name="node2" as="node()" select="~"/> 4<xsl:choose> 5 <xsl:when test="$node1 is $node2"> 6 <!-- 同じ場合の処理 --> 7 </xsl:when> 8 <xsl:otherwise> 9 <!--異なる場合の処理--> 10 </xsl:otherwise> 11</xsl:choose>
では、次のような場合、$nodes1と$nodes2の同一性は、どんな関数(xsl:function)をつくれば得ることができるでしょう.$nodes1, $nodes2とも並びはドキュメントオーダーが保証されていないものとします.
xml
1<!--"~"は適当なXPath式を示します--> 2<xsl:variable name="nodes1" as="node()*" select="~"/> 3<xsl:variable name="nodes2" as="node()*" select="~"/>
該当のソースコード
こんな関数になると思います.
xml
1<!--望まれる関数のインタフェース、ネームスペースは適当です--> 2<xsl:function name="ahf:compareNodes" as="xs:boolean"> 3 <xsl:param name="prmNodes1" as="node()*"/> 4 <xsl:param name="prmNodes2" as="node()*"/> 5 <!--関数のコード本体--> 6 <!-- $prmNodes1と$prmNodes2の同一性を判定して 7 結果をtrue()かfalse()で返す 8 --> 9</xsl:function>
試したこと・調べたこと
- teratailやGoogle等で検索した
- ソースコードを自分なりに変更した
- 知人に聞いた
- その他
上記の詳細・結果
調べましたが同じような質問はありませんでした.
補足
会社の同僚に同じ質問をしていて聞かれました.$nodes1, $nodes2に各々重複があった場合どう考えるのか?というもの.聞く方の立場からすれば、重複があった場合それを省いて比較していただければ良いです.例を示しますと.以下のような場合、$nodes1と$nodes2と$nodes3は「同じ」とみなしてもらって結構です.つまり重複を削除したノードの集合同士の比較ということになります.
xml
1 <xsl:variable name="tree" as="document-node()" > 2 <xsl:document> 3 <a/><b/><c/><d/> 4 </xsl:document> 5 </xsl:variable> 6 7 <xsl:variable name="nodes1" as="node()+" select="($tree/*[1],$tree/*[2],$tree/*[3])" /> 8 <xsl:variable name="nodes2" as="node()+" select="($tree/*[3],$tree/*[2],$tree/*[1])" /> 9 <xsl:variable name="nodes3" as="node()+" select="($tree/*[3],$tree/*[2],$tree/*[1],$tree/*[3])" />
同様に会社の同僚から「$nodes1と$nodes2の同一性」とは何か?と聞かれました、これは次のように考えることができます.
- $nodes1のすべてのnode()の「node identity」が等しいnode()が$nodes2に存在し
- 逆に$nodes2のすべてのnode()の「node identity」が等しいnode()が$nodes1に存在する
これが満たされることです.
node identity については以下に(むつかしいですが)定義があります.
2.3 Node Identity
くだいていえば$node1と$node2(共に単一のnode())のnode identityが等しいとは、XSLT 1.0の以下の式が成り立つ場合と考えれば良いと思います.(これは独自解釈)
generate-id($node1) = generate-id($node2)
つまり$node1と$node2が同じツリーに属していて、ドキュメントオーダーで同じ位置にあればgenerate-id()は等しくなるはずです.
In other cases, the function returns a string that uniquely identifies a given node. More formally, it is guaranteed that within a single ·execution scope·, fn:codepoint-equal(fn:generate-id($N), fn:generate-id($M)) returns true if and only if ($M is $N) returns true.
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2024/08/12 08:14
2024/08/12 09:32
2024/08/12 11:25