Чтобы сравнить два элемента (тип строки) в XSLT?

Я новичок в XSLT, может ли кто-нибудь предложить мне, как сравнить два элемента, исходящих из xml, как строку, их значения:

<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>

Ответы

Ответ 1

Прежде всего, предоставленный длинный код:

    <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 как строка

В Xpath 1.0 строки можно сравнивать только для равенства (или неравенства), используя оператор = и функцию not() вместе с оператором =.

$str1 = $str2

принимает значение true() точно, когда строка $str1 равна строке $str2.

not($str1 = $str2)

принимает значение true() точно, когда строка $str1 не равна строке $str2.

Существует также оператор !=. Его вообще следует избегать, поскольку он имеет аномальное поведение, когда один из его операндов представляет собой node -set.

Теперь правила сравнения двух узлов элемента аналогичны:

$el1 = $el2

принимает значение true() точно, когда строковое значение $el1 равно строковому значению $el2.

not($el1 = $el2)

принимает значение true() точно, когда строковое значение $el1 не равно строковому значению $el2.

Однако, если один из операндов = является node -set, то

 $ns = $str

принимает значение true() точно, когда в node -set $ns1 присутствует хотя бы один node, строковое значение которого равно строке $str

$ns1 = $ns2

оценивается как true() точно, когда в node -set $ns1 есть как минимум один node, строковое значение которого соответствует строковому значению некоторого node из $ns2

Следовательно, выражение:

OU_NAME='OU_ADDR1'

оценивает true() только в том случае, если существует хотя бы один дочерний элемент из текущего node, который имеет имя OU_NAME и строковым значением которого является строка 'OU_ADDR1'.

Это явно не то, что вы хотите!

Скорее всего, вы хотите:

OU_NAME=OU_ADDR1

Это выражение оценивается как true. Существует ровно один дочерний OU_NAME текущего node и один OU_ADDR1 дочерний элемент текущего node с тем же строковым значением.

Наконец, в XPath 2.0 строки можно сравнить также с помощью операторов сравнения значений lt, le, eq, gt, ge и унаследованных от XPath 1.0 общий оператор сравнения =.

Попытка оценить оператор сравнения значений, когда один или оба его аргумента являются последовательностью более одного элемента, приводит к ошибке.