読者です 読者をやめる 読者になる 読者になる

そごうソフトウェア研究所

SOA、開発プロセス、ITアーキテクチャなどについて書いています。Twitterやってます@rsogo

XQueryによる条件分岐と文字列操作

前回のXQueryによる要素抽出と文字列操作に引き続き、XQueryをやります。前回はwhereを使った条件による抽出でした。


今回は、条件分岐を使ってAならばBする、AでないならばCするという処理を試します。


使用するスキーマ定義は前回と同じです。

<xsd:element name="SimpleServiceMsg">
    <xsd:complexType>
      <xsd:sequence>
          <xsd:element name="SimpleRecords" minOccurs="1" maxOccurs="unbounded">
             <xsd:complexType>
                  <xsd:sequence>
                      <xsd:element name="input0" type="xsd:string"/>
                      <xsd:element name="input1" type="xsd:string"/>
                      <xsd:element name="input2" type="xsd:string"/>
                      <xsd:element name="input3" type="xsd:string"/>
                      <xsd:element name="input4" type="xsd:string"/>
                      <xsd:element name="input5" type="xsd:string"/>
                      <xsd:element name="input6" type="xsd:dateTime"/>
                      <xsd:element name="input7" type="xsd:boolean"/>
                      <xsd:element name="input8" type="xsd:decimal"/>
                      <xsd:element name="input9" type="xsd:integer"/>
                  </xsd:sequence>
             </xsd:complexType>
          </xsd:element>
       </xsd:sequence>
   </xsd:complexType>
</xsd:element> 


変換要件2

  • XQueryで、input0要素の値の文字長が9桁であるSimpleRecords要素を抽出し、先頭を0埋めして10桁にする。
  • 文字長が9桁でないものは、文字列操作をせずに、そのままの値を返す

XQuery回答例

if/then/elseを使います。
if(条件)
then
 条件が真の場合の処理
else
 条件が偽の場合の処理

C言語と同じですね。

                if (fn:string-length($SimpleRecords/ns2:input0) = 9)
                then
                   let $result := fn:concat("0", $SimpleRecords/ns2:input0/text())
                   return $result
                else
                   let $result := $SimpleRecords/ns2:input0/text()
                   return $result

文字列の長さはfn:string-length関数を使用し、fn:concatを使って文字列連結しているのは前回と同じです。

全体としては以下。前回と同じく入れ子のXQuery処理でメッセージ全体を作っています。

<SimpleServiceMsg>
    {
        for $SimpleRecords in $simpleServiceMsg1/SimpleRecords
        return
            <SimpleRecords>
            <input0>
            {
                if (fn:string-length($SimpleRecords/ns2:input0) = 9)
                then
                   let $result := fn:concat("0", $SimpleRecords/ns2:input0/text())
                   return $result
                else
                   let $result := $SimpleRecords/ns2:input0/text()
                   return $result
 
            }</input0>
            <input1>{ data($SimpleRecords/input1) }</input1>
            <input2>{ data($SimpleRecords/input2) }</input2>
            <input3>{ data($SimpleRecords/input3) }</input3>
            <input4>{ data($SimpleRecords/input4) }</input4>
            <input5>{ data($SimpleRecords/input5) }</input5>
            <input6>{ data($SimpleRecords/input6) }</input6>
            <input7>{ data($SimpleRecords/input7) }</input7>
            <input8>{ data($SimpleRecords/input8) }</input8>
            <input9>{ data($SimpleRecords/input9) }</input9>
    </SimpleRecords>
    }
</SimpleServiceMsg>


XQueryのめんどくさい所は、簡単に試すための処理系が普及していないことだと思います。
Javaが標準でサポートしてくれたらいいんですけど。
$simpleServiceMsg1のような変数に、ファイルやHTTPリクエストから取ってきたXMLメッセージをセットするところは処理系に依存します。