web-dev-qa-db-ja.com

XSLTの2つの要素(文字列型)を比較するには?

私はXSLTを初めて使用していますが、xmlからの2つの要素を文字列として比較する方法を提案できますか?

<OU_NAME>Vision Operations</OU_NAME> --XML code
<OU_ADDR1>90 Fifth Avenue</OU_ADDR1> --XML code

<xsl:choose>
    <xsl:when test="OU_NAME='OU_ADDR1'"> --comparing two elements coming from XML
        <!--remove if  adrees already contain  operating unit name
            <xsl:value-of select="OU_NAME"/> <fo:block/>-->
        <xsl:if test="OU_ADDR1 !='' ">
            <xsl:value-of select="OU_ADDR1"/>
            <fo:block/>
        </xsl:if>
        <xsl:if test="LE_ADDR2 !='' ">
            <xsl:value-of select="OU_ADDR2"/>
            <fo:block/>
        </xsl:if>
        <xsl:if test="LE_ADDR3 !='' ">
            <xsl:value-of select="OU_ADDR3"/>
            <fo:block/>
        </xsl:if>
        <xsl:if test="OU_TOWN_CITY !=''">
            <xsl:value-of select="OU_TOWN_CITY"/>,
            <fo:leader leader-pattern="space" leader-length="2.0pt"/>
        </xsl:if>
        <xsl:value-of select="OU_REGION2"/>
        <fo:leader leader-pattern="space" leader-length="3.0pt"/>
        <xsl:value-of select="OU_POSTALCODE"/>
        <fo:block/>
        <xsl:value-of select="OU_COUNTRY"/>
    </xsl:when>
    <xsl:otherwise>
        <xsl:value-of select="OU_NAME"/>
        <fo:block/>
        <xsl:if test="OU_ADDR1 !='' ">
            <xsl:value-of select="OU_ADDR1"/>
            <fo:block/>
        </xsl:if>
        <xsl:if test="LE_ADDR2 !='' ">
            <xsl:value-of select="OU_ADDR2"/>
            <fo:block/>
        </xsl:if>
        <xsl:if test="LE_ADDR3 !='' ">
            <xsl:value-of select="OU_ADDR3"/>
            <fo:block/>
        </xsl:if>
        <xsl:if test="OU_TOWN_CITY !=''">
            <xsl:value-of select="OU_TOWN_CITY"/>,
            <fo:leader leader-pattern="space" leader-length="2.0pt"/>
        </xsl:if>
        <xsl:value-of select="OU_REGION2"/>
        <fo:leader leader-pattern="space" leader-length="3.0pt"/>
        <xsl:value-of select="OU_POSTALCODE"/>
        <fo:block/>
        <xsl:value-of select="OU_COUNTRY"/>
    </xsl:otherwise>
</xsl:choose>
16
Vineet

まず、提供された長いコード

    <xsl:choose>
        <xsl:when test="OU_NAME='OU_ADDR1'">   --comparing two elements coming from XML             
            <!--remove if  adrees already contain  operating unit name <xsl:value-of select="OU_NAME"/> <fo:block/>-->
            <xsl:if test="OU_ADDR1 !='' ">
                <xsl:value-of select="OU_ADDR1"/>
                <fo:block/>
            </xsl:if>
            <xsl:if test="LE_ADDR2 !='' ">
                <xsl:value-of select="OU_ADDR2"/>
                <fo:block/>
            </xsl:if>
            <xsl:if test="LE_ADDR3 !='' ">
                <xsl:value-of select="OU_ADDR3"/>
                <fo:block/>
            </xsl:if>
            <xsl:if test="OU_TOWN_CITY !=''">
                <xsl:value-of select="OU_TOWN_CITY"/>,
                <fo:leader leader-pattern="space" leader-length="2.0pt"/>
            </xsl:if>
            <xsl:value-of select="OU_REGION2"/>
            <fo:leader leader-pattern="space" leader-length="3.0pt"/>
            <xsl:value-of select="OU_POSTALCODE"/>
            <fo:block/>
            <xsl:value-of select="OU_COUNTRY"/>
        </xsl:when>
        <xsl:otherwise>
            <xsl:value-of select="OU_NAME"/>
            <fo:block/>
            <xsl:if test="OU_ADDR1 !='' ">
                <xsl:value-of select="OU_ADDR1"/>
                <fo:block/>
            </xsl:if>
            <xsl:if test="LE_ADDR2 !='' ">
                <xsl:value-of select="OU_ADDR2"/>
                <fo:block/>
            </xsl:if>
            <xsl:if test="LE_ADDR3 !='' ">
                <xsl:value-of select="OU_ADDR3"/>
                <fo:block/>
            </xsl:if>
            <xsl:if test="OU_TOWN_CITY !=''">
                <xsl:value-of select="OU_TOWN_CITY"/>,
                <fo:leader leader-pattern="space" leader-length="2.0pt"/>
            </xsl:if>
            <xsl:value-of select="OU_REGION2"/>
            <fo:leader leader-pattern="space" leader-length="3.0pt"/>
            <xsl:value-of select="OU_POSTALCODE"/>
            <fo:block/>
            <xsl:value-of select="OU_COUNTRY"/>
        </xsl:otherwise>
    </xsl:choose>

これと同等、はるかに短いコード

<xsl:if test="not(OU_NAME='OU_ADDR1)'">
              <xsl:value-of select="OU_NAME"/>
        </xsl:if>
            <xsl:if test="OU_ADDR1 !='' ">
                <xsl:value-of select="OU_ADDR1"/>
                <fo:block/>
            </xsl:if>
            <xsl:if test="LE_ADDR2 !='' ">
                <xsl:value-of select="OU_ADDR2"/>
                <fo:block/>
            </xsl:if>
            <xsl:if test="LE_ADDR3 !='' ">
                <xsl:value-of select="OU_ADDR3"/>
                <fo:block/>
            </xsl:if>
            <xsl:if test="OU_TOWN_CITY !=''">
                <xsl:value-of select="OU_TOWN_CITY"/>,
                <fo:leader leader-pattern="space" leader-length="2.0pt"/>
            </xsl:if>
            <xsl:value-of select="OU_REGION2"/>
            <fo:leader leader-pattern="space" leader-length="3.0pt"/>
            <xsl:value-of select="OU_POSTALCODE"/>
            <fo:block/>
            <xsl:value-of select="OU_COUNTRY"/>

今、あなたの質問に:

文字列としてxmlから来る2つの要素を比較する方法

Xpath 1.0では、演算子=と関数not()を演算子=とともに使用して、文字列を等しい(または不等式)のみ比較できます。

$str1 = $str2

文字列$str1が文字列$str2と等しい場合、正確にtrue()と評価されます。

not($str1 = $str2)

文字列$str1が文字列$str2と等しくない場合、正確にtrue()と評価されます。

!=演算子もあります。オペランドの1つがノードセットである場合は常に異常な動作をするため、通常は避ける必要があります。

現在、2つの要素ノードを比較するためのルールは似ています

$el1 = $el2

$el1の文字列値が$el2の文字列値と等しい場合、正確にtrue()に評価されます。

not($el1 = $el2)

$el1の文字列値が$el2の文字列値と等しくない場合、正確にtrue()に評価されます。

ただし、=のオペランドの1つがノードセットの場合、

 $ns = $str

ノードセット$ns1に少なくとも1つのノードがあり、その文字列値が文字列$strと等しい場合、正確にtrue()に評価されます

$ns1 = $ns2

ノードセット$ns1に少なくとも1つのノードがあり、その文字列値が$ns2のノードの文字列値と等しい場合、正確にtrue()に評価されます

したがって、式

OU_NAME='OU_ADDR1'

true()と評価されるのは、OU_NAMEという名前の現在のノードの子要素が少なくとも1つあり、その文字列値が文字列 'OU_ADDR1'である場合のみです。

これは明らかにあなたが望むものではありません!

おそらくあなたが望む:

OU_NAME=OU_ADDR1

この式は、現在のノードの少なくとも1つのOU_NAME子と、同じ文字列値を持つ現在のノードの1つのOU_ADDR1子が正確にtrueと評価されます。

最後に、XPath 2.0では、値比較演算子ltleeqgtを使用して文字列を比較することもできます、geおよびXPath 1.0の一般的な比較演算子から継承された=

引数の一方または両方が複数のアイテムのシーケンスである場合に値比較演算子を評価しようとすると、エラーが発生します。

35