パラメータとシーケンス

www.altova.com このトピックを印刷 前のページ 1つ上のレベル 次のページ

ホーム >  SPS ファイル: 追加機能 > ユーザー定義 XPath 関数 > XPath 関数内のパラメーター >

パラメータとシーケンス

ここでパラメーターとシーケンスの関係と、パラメーターとシーケンスが XPath 条件式でどのように使用されるかを理解しておくべきでしょう。以下のようにこれらの用語を定義します:

 

シーケンスは、アトミック値またはノードからなるアイテムにより構成されます。シーケンスのアイテム間にコンマを使用することでシーケンスを構築することができます。
XPath 2.0 関数はパラメーターを受け取るように定義することができます。例えば、関数の定義にて使用される count($a) という XPath 2.0 条件式における括弧内の値 $a が関数のパラメーターとなります。
引数は関数呼び出しにて使用されるアイテムのことです。例えば、count(//Person) という関数呼び出しでは //Person という引数が与えられています。この引数によりノードのシーケンスが count() の引数として与えられることになります。
substring('styleVisionExamples', 6, 6) という関数の呼び出しでは3つの引数が与えられており、Vision という文字列が返されます。この呼び出しは substring() 関数の定義に対して妥当なものとなります。関数の呼び出しにて複数の引数が与えられた場合、それらはコンマにより区切られることになります。

 

シーケンスの区切りとして使用される括弧

XPath 2.0 条件式を構築する際には、コンマにより区切られたアイテムや範囲演算子により構成されるシーケンスを区切るために括弧が使用され、結果として括弧により区切られたシーケンスは1つのパラメーターまたは引数として読み取られるということに留意してください。

 

パス条件式は単一のパラメーターまたは単一の引数として読み取られるため、//Person/@salary といったパス(ロケーター)条件式の周りで括弧を使用する必要は必ずしもありません。パス条件式は単一のパラメーター/引数からなるシーケンスとなります。

 

上の説明を補足するための例を以下に示します:

 

avg((10, 20, 30)) : XPath 2.0 の avg 関数は、複数のアイテムが含まれているシーケンスを1つ引数として受け取ります。シーケンスに含まれるアイテムはコンマにより区切られているので、単一のシーケンスを区切るために内部の括弧が必要になります。この括弧が無い場合、3つの引数が与えられることになり、関数呼び出しは不正なものとなります(外型の括弧は関数に対する括弧となります)。
avg(//Person/@salary) : パス条件式により、全 Person 要素のノードにある salary 属性が選択され、その属性値がシーケンスとして返されます。引数が読み取られる前にシーケンスが列挙されることは無いため、括弧をつける必要はありません。単一のパス(ロケーター)条件式が引数となります。パス条件式が評価され、その結果がシーケンスのアイテムとして関数へ与えられます。
count((10 to 34)) : 範囲演算子による列挙が行われます。引数が読み取られる前に、範囲演算子の 'to' により、コンマにより区切られたアイテムのシーケンスが生成されます。そのため、count() 関数呼び出しの引数にはコンマにより区切られた25個のアイテムが含まれることになります。これらのアイテムを単一のシーケンスとして読み取るためには、括弧を使用する必要があります。括弧が使用されない場合、関数呼び出しに25個の引数が与えられることになり、(count() 関数の引数には単一のシーケンスを使用する必要があるため)関数呼び出しが不正なものとなってしまいます。
count((10 to 34, 37)) : 内側の括弧により、括弧内部のアイテムにより構成される1つのシーケンスが関数呼び出しに使用されます。この例では26個のアイテムからなる単一のシーケンスが与えられます。
count(//Person) : 単一の引数を与える場合、シーケンスの区切りとなる括弧を使用する必要はありません。XML ドキュメント内にある //Person ノードを選択するパス条件式が引数として使用され、選択されたノードがシーケンスのアイテムとして渡されます。

 

XPath 関数にて XPath パラメータを使用する

括弧がユーザー定義 XPath 関数にて使用された場合、(i) 関数呼び出しに使用された引数の数がユーザー定義 XPath 関数のそれとマッチするか、そして (ii) 期待されている型と出現に対して個々の引数が評価されるかを確認する必要があります。

 

XPFxThreeAverage

 

上のスクリーンショットでは、3つのパラメーターが(パラメーターペインにて)定義されており、これらのパラメーターを関数ボディーペインで使用することにより、XPath 関数が定義されています。

 

パラメーターにて定義された各パラメーターは、それぞれ単一のシーケンスとして考えることができます。出現プロパティでは、それぞれのシーケンスにて許されることになるアイテムの数が指定されます。上のスクリーンショットに示される定義では、各パラメーターがシングルトンシーケンス(つまりアイテムが1つだけ含まれるシーケンス)として定義されています。そのため、関数呼び出しの各引数には、アイテムが1つ含まれるシーケンスが使用されることになります。プロパティにより、シーケンスのアイテムに対するデータ型が指定されます。

 

関数ボディーペインにある XPath 関数の定義では、それぞれ1つのアイテムから構成されるシーケンスがパラメーターにより与えられ、それらの平均が求められます。これらの XPath パラメーターによりシーケンスが構成されるため、これらのパラメーターを括弧で囲み、単一のシーケンスとして avg() 関数へ引数を渡す必要があります。ランタイムにて与えられる(3つのパラメーターに対応する)関数呼び出しの引数がシングルトンシーケンスでない場合、エラーが返されます。

 

上のスクリーンショットに示される XPath 関数の ThreeAverage() を呼び出すための XPath パラメーターの例を以下に示します。デザインビューにて自動計算を挿入し、以下に示される XPath 条件式を使用することで、結果を確認することができます。関数には integer 型の引数が3つ与えられ、それらの平均が返されます。

 

 

sps:ThreeAverage(10,20,30) により 20 が返されます。関数呼び出しには XPath 関数のパラメーターにマッチする妥当な3つの引数が使用されています。
sps:ThreeAverage( (10),(20),(30) ) により 20 が返されます。3つの XPath パラメータ に対応する、3つの妥当な入力引数が存在します。 各入力引数は、(各シーケンスが単一のシーケンスであるために、重複している、しかしながら重複はエラーではない)  括弧で囲まれています
sps:ThreeAverage( (10),20,30 ) により 20 が返されます。XPath 関数のパラメーターに対応する妥当な引数が3つ与えられています。第1引数が括弧で囲まれており、これは冗長な表現ですがエラーとはなりません。
sps:ThreeAverage( (10,20),(30),(40) ) によりエラーが返されます。第1引数がシングルトンシーケンスでは無いため、エラーとなります($a パラメーターの型プロパティには、「1つ」が指定されています)。
sps:ThreeAverage( (10,20,30) ) によりエラーが返されます。引数として与えられているのは括弧により囲まれたシーケンスが1つだけで、XPath 関数のパラメーター数にマッチしません。更に、シーケンスもシングルトンシーケンスではないため、不正となります。

 

 

パラメーターの出現プロパティに最低1つがセットされた場合、1つまたは複数のアイテムを含むシーケンスを引数として使用することができます(以下のスクリーンショットを参照)。

 

XPFxThreeAverageNCount

 

上にある定義では、最初のパラメーターに対して1つ以上のアイテムが含まれるシーケンスが定義され、残り2つのパラメーターに対してシングルトンシーケンスが定義されています。最初のパラメーターに対して渡されたアイテムの数を数え、その数と、その他2つのパラメーターに対して渡された数の平均を返すように関数は定義されています。以下の点に注目してください:

 

avg() 関数の呼び出しに使われる引数は括弧で囲まれています。これにより、3つのアイテムからなるシーケンスが、引数として avg() へ渡されます。count() 関数から返される値が最初のシーケンスアイテムに、パラメーター $b$c がそれぞれ2番目と3番目のシーケンスアイテムになります。
count() 関数呼び出しの引数は単一のシーケンスであることが明らかなので、括弧で囲まれていません。

 

上のスクリーンショットにて示される Average() XPath 関数を呼び出す際に使用する引数の例を以下に示します:

 

sps:Average((1,2),3,4) により 3 が返されます。パラメーターに対応する3つの妥当な引数が与えられています。最初の引数は括弧により囲まれており、他の(シングルトン)シーケンスと区切られています。第1引数に対して count() 関数が処理され、2 という値が返され、その値が avg() 関数に渡されるシーケンスにおける最初のアイテムとして使用されます。
sps:Average( 4,4,4 ) により 3 が返されます。妥当な引数が3つ与えられています。最初の引数は1つのアイテムにより構成されるシーケンスでも良いため、他の引数と区別するために括弧を使用する必要はありません(対応するパラメーターの出現プロパティを参照ください)。

 

その他の留意するべき点

以下の点にも留意しておく必要があります:

 

XPath 引数の出現に最低1つがセットされている場合、avg(($a)) といった XPath 条件式を関数ボディーとする MyAverage() といった関数を定義することができます。この関数の引数には、1つ以上のアイテムが含まれるシングルトンシーケンスが渡されます。関数は、例えば sps:((2,3,4)) という呼び出しにより 3 という値が返されます。3つのシングルトンシーケンスではなく、単一のシーケンスとして引数を渡すために、引数は括弧で囲む必要があります。
XPath パラメーターの $a の出現プロパティに無しまたは1つが指定された場合、avg($a, $b, $c) といった XPath 条件式により構成される MyAverage() といった関数を定義することができます。この関数には3つのシーケンスが引数として渡されるだけではなく、最初の引数値を空にすることも可能になります。最初のシーケンスを空にする場合、空のシーケンスを最初の引数値として明示的に渡す必要があります(そうでない場合エラーが返されます)。sps:MyAverage(30, 20, 10) により関数の呼び出しを行うと、20 という値が返されます。sps:MyAverage((), 20, 10) という関数の呼び出しが行われた場合、(最初のシーケンスが空の入力値としてカウントされるため)15 という値が返されます。それに対して sps:MyAverage(20, 10) という関数の呼び出しでは最初の(空の)シーケンスが明示的に示されておらず、第3引数が与えられていないと認識され、エラーが返されます。

 

複雑な例

XPath 条件式を再利用するという以外にも、ユーザー定義の XPath 関数を使用することで、XPath 2.0 の関数セットでは提供されていない、複雑でカスタマイズされた XPath 関数を構築することができます。例えば、シングルトンシーケンスを引数として受け取る XPath 条件式を使用することで、階乗関数を簡単に作成することができます。$num という引数が求める階乗の数だとすると、関数を構成する XPath 条件式は以下のようになります:

 

if ($num < 2) then 1 else $num * sps:Factorial($num - 1)

 

関数の名前を Factorial() とすると、例えば sps:Factorial(6) という関数呼び出しにより 6 の階乗を求めることができます。

 


(C) 2019 Altova GmbH