9

私はこのXMLを持っています:

<property id="1011">
    <leasehold>No</leasehold>
    <freehold>Yes</freehold>
    <propertyTypes>
        <propertyType>RESIDENTIAL</propertyType>
    </propertyTypes>
</property>

そして、次のネストされた if-else 疑似コード ブロックと同じ xpath ステートメントを作成したいと考えています。

if( propertyTypes/propertyType == 'RESIDENTIAL') {
    if( leasehold == 'Yes' ){
        return 'Rent'
    } else
        return 'Buy'
    }
} else {
    if( leasehold == 'Yes' ){
        return 'Leasehold'
    } else
        return 'Freehold'
    }
}

ベッカーの方法について何か見たことがありますが、実際には従うことができませんでした。XPath は私の得意分野ではありません。

4

4 に答える 4

22

I. XPath 2.0 では、これを単純に次のように変換します。

   if(/*/propertyTypes/propertyType = 'RESIDENTIAL')
    then
     (if(/*/leasehold='Yes')
       then 'Rent'
       else 'Buy'
     )
     else
       if(/*/leasehold='Yes')
         then 'Leasehold'
         else 'Freehold'

XSLT 2.0 ベースの検証:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xs="http://www.w3.org/2001/XMLSchema">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/">
  <xsl:sequence select=
   "if(/*/propertyTypes/propertyType = 'RESIDENTIAL')
   then
     (if(/*/leasehold='Yes')
       then 'Rent'
       else 'Buy'
     )
     else
       if(/*/leasehold='Yes')
         then 'Leasehold'
         else 'Freehold'
   "/>
 </xsl:template>
</xsl:stylesheet>

この変換が提供された XML ドキュメントに適用されると、次のようになります。

<property id="1011">
    <leasehold>No</leasehold>
    <freehold>Yes</freehold>
    <propertyTypes>
        <propertyType>RESIDENTIAL</propertyType>
    </propertyTypes>
</property>

XPath 式が評価され、この評価の結果が出力にコピーされます。

Buy

Ⅱ.XPath 1.0 ソリューション

XPath 1.0 にはif演算子がありません。

条件付きステートメントは、単一の XPath 1.0 式で実装できますが、これはよりトリッキーであり、式が読みにくく、理解しにくい場合があります。

$stringA条件$condtrue()である場合に を生成し、そうでない場合に を生成する一般的な方法 (Jeni Tennison によって最初に提案された) を次に示し$stringBます。

concat(substring($stringA, 1 div $cond), substring($stringB, 1 div not($cond)))

この式の主な成果の 1 つは、任意の長さの文字列に対して機能し、長さを指定する必要がないことです。

説明:

ここでは、定義により次の事実を使用します。

number(true()) = 1

number(false()) = 0

そしてそれ

1 div 0 = Infinity

したがって、 が$condの場合false、上記の最初の引数は次のconcat()ようになります。

 substring($stringA, Infinity)

$stringA これは、長さが有限であるため、空の文字列です。

反対に、上記の最初の引数は次の$condとおりです。true()concat()

sibstring($stringA, 1) 

それだけ$stringAです。

$condしたがって、上記の 2 つの引数のうちの 1 つだけの値に応じてconcat()、空でない文字列 (それぞれ$stringAまたは$stringB) になります。

この一般的な式を特定の質問に適用すると、大きな条件式の前半を次のように変換できます。

concat(
           substring('rent',
                      1 div boolean(/*[leasehold='Yes'
                                     and
                                       propertyTypes/propertyType = 'RESIDENTIAL'
                                      ]
                                  )
                      ),
           substring('buy',
                      1 div not(/*[leasehold='Yes'
                                     and
                                       propertyTypes/propertyType = 'RESIDENTIAL'
                                      ]
                                  )
                      )
               )

これにより、条件式全体を単一の XPath 1.0 式に変換する方法がわかります。

XSLT 1.0 ベースの検証:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/">
  <xsl:copy-of select=
   "concat(
           substring('rent',
                      1 div boolean(/*[leasehold='Yes'
                                     and
                                       propertyTypes/propertyType = 'RESIDENTIAL'
                                      ]
                                  )
                      ),
           substring('buy',
                      1 div not(/*[leasehold='Yes'
                                     and
                                       propertyTypes/propertyType = 'RESIDENTIAL'
                                      ]
                                  )
                      )
               )
   "/>
 </xsl:template>
</xsl:stylesheet>

この変換が提供された XML ドキュメント (上記) に適用されると、XPath 式が評価され、この評価の結果が出力にコピーされます。

buy

注意してください:

特定の文字列を元の文字列とは異なる長さの別の文字列に置き換える場合は、上記の XPath 1.0 式でこれらの文字列を置き換えるだけで、長さの指定について心配する必要はありません。

于 2012-10-19T15:34:13.533 に答える
2

データに対するベッカーの方法は次のとおりです。

concat(substring('Rent',      1 div boolean(propertyTypes/propertyType ="RESIDENTIAL" and leasehold="Yes")),
       substring('Buy',       1 div boolean(propertyTypes/propertyType ="RESIDENTIAL" and leasehold="No")),
       substring('Leasehold', 1 div boolean(propertyTypes/propertyType!="RESIDENTIAL" and leasehold="Yes")),
       substring('Freehold',  1 div boolean(propertyTypes/propertyType!="RESIDENTIAL" and leasehold="No")))
于 2012-10-19T15:39:11.503 に答える
0

これを試して

if (condition) 
then 
  if (condition) stmnt 
  else stmnt 
else 
  if (condition) stmnt 
  else stmnt 
于 2012-10-19T15:30:53.643 に答える