質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.36%
XML

XMLは仕様の1つで、マークアップ言語群を構築するために使われています。

XPath(XML Path)

XML Path Language (XPath; XMLパス言語)は、マークアップ言語 XML に準拠した文書の特定の部分を指定する言語構文の事をいいます。XPathはXMLとは別の構文を使用します。XMLドキュメントの抽象、論理ストラクチャ上で動作します。

XSLT

XSLTは、組み立てられた文書を(XML、HTML、そしてプレーンテキストのような)別のフォーマットに変化する為にデザインされたXMLの為の変換用言語です。

Q&A

解決済

1回答

274閲覧

node()* を node()* と比較する

tmakita

総合スコア70

XML

XMLは仕様の1つで、マークアップ言語群を構築するために使われています。

XPath(XML Path)

XML Path Language (XPath; XMLパス言語)は、マークアップ言語 XML に準拠した文書の特定の部分を指定する言語構文の事をいいます。XPathはXMLとは別の構文を使用します。XMLドキュメントの抽象、論理ストラクチャ上で動作します。

XSLT

XSLTは、組み立てられた文書を(XML、HTML、そしてプレーンテキストのような)別のフォーマットに変化する為にデザインされたXMLの為の変換用言語です。

0グッド

2クリップ

投稿2024/08/08 14:59

編集2024/08/09 11:02

実現したいこと

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の同一性」とは何か?と聞かれました、これは次のように考えることができます.

  1. $nodes1のすべてのnode()の「node identity」が等しいnode()が$nodes2に存在し
  2. 逆に$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()は等しくなるはずです.

14.5.4 fn: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.

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

$nodes1のすべてのnode()の「node identity」が等しいnode()が$nodes2に存在し
逆に$nodes2のすべてのnode()の「node identity」が等しいnode()が$nodes1に存在する

それをそのまま表現して

(every $node1 in $prmNodes1 satisfies some $node2 in $prmNodes2 satisfies $node1 is $node2) and (every $node2 in $prmNodes2 satisfies some $node1 in $prmNodes1 satisfies $node1 is $node2)

でしょうか?
ahf:compareNodes((),())の場合をどう定義するかによっては、exists($prmNodes1) and exists($prmNodes2)を追加する必要があるかも)

投稿2024/08/12 06:03

OACleaner

総合スコア72

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tmakita

2024/08/12 08:14

回答ありがとうございます。 試したところ問題が解決しました! テストのテンプレート ```xml <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:ahf="http://www.antennahouse.com/names/XSLT/Functions/Document" exclude-result-prefixes="#all"> <xsl:variable name="tree" as="document-node()" > <xsl:document> <a/><b/><c/><d/> </xsl:document> </xsl:variable> <xsl:variable name="nodes1" as="node()+" select="($tree/*[1],$tree/*[2],$tree/*[3])" /> <xsl:variable name="nodes2" as="node()+" select="($tree/*[3],$tree/*[2],$tree/*[1])" /> <xsl:variable name="nodes3" as="node()+" select="($tree/*[3],$tree/*[2],$tree/*[1],$tree/*[3])" /> <xsl:variable name="nodes4" as="node()+" select="($tree/*[1],$tree/*[2],$tree/*[3],$tree/*[4])" /> <xsl:variable name="nodesNull" as="node()*" select="()" /> <xsl:template match="/"> <result> <xsl:value-of select="'&#x0A;ahf:nodesComp($nodes1,$nodes2)=' || ahf:nodesComp($nodes1,$nodes2)"/> <xsl:value-of select="'&#x0A;ahf:nodesComp($nodes1,$nodes3)=' || ahf:nodesComp($nodes1,$nodes3)"/> <xsl:value-of select="'&#x0A;ahf:nodesComp($nodes1,$nodes4)=' || ahf:nodesComp($nodes1,$nodes4)"/> <xsl:value-of select="'&#x0A;ahf:nodesComp($nodesNull,$nodesNull)=' || ahf:nodesComp($nodesNull,$nodesNull)"/> </result> </xsl:template> <xsl:function name="ahf:nodesComp" as="xs:boolean"> <xsl:param name="prmNodes1" as="node()*"/> <xsl:param name="prmNodes2" as="node()*"/> <xsl:choose> <xsl:when test="(every $node1 in $prmNodes1 satisfies some $node2 in $prmNodes2 satisfies $node1 is $node2) and (every $node2 in $prmNodes2 satisfies some $node1 in $prmNodes1 satisfies $node1 is $node2) "> <xsl:sequence select="true()"/> </xsl:when> <xsl:otherwise> <xsl:sequence select="false()"/> </xsl:otherwise> </xsl:choose> </xsl:function> </xsl:stylesheet> ``` 出力 ```xml <?xml version="1.0" encoding="UTF-8"?><result> ahf:nodesComp($nodes1,$nodes2)=true ahf:nodesComp($nodes1,$nodes3)=true ahf:nodesComp($nodes1,$nodes4)=false ahf:nodesComp($nodesNull,$nodesNull)=true</result> ``` 確かに両方のパラメータが () の場合はtrue()にしないほうがいいかもしれませんね.
OACleaner

2024/08/12 09:32

empty($prmNodes1 except $prmNodes2) and empty($prmNodes2 except $prmNodes1) のほうがシンプルで良かったかもしれません。
tmakita

2024/08/12 11:25

はい、私もあとで考えてコメントの答えにたどり着きました.内部的にやっていることは同じなのかもしれませんが、そちらの方がスマートですね.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問