Сравнить два элемента (строковый тип) в 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>

person Vineet    schedule 13.04.2011    source источник


Ответы (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.

Также есть оператор !=. Как правило, его следует избегать, потому что он имеет аномальное поведение, когда один из его операндов является набором узлов.

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

$el1 = $el2

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

not($el1 = $el2)

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

Однако, если один из операндов = является набором узлов, то

 $ns = $str

оценивается как true() ровно тогда, когда в наборе узлов $ns1 есть хотя бы один узел, строковое значение которого равно строке $str

$ns1 = $ns2

оценивается как true() ровно тогда, когда в наборе узлов $ns1 есть хотя бы один узел, строковое значение которого равно строковому значению некоторого узла из $ns2

Поэтому выражение:

OU_NAME='OU_ADDR1'

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

Это явно не то, что вам нужно!

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

OU_NAME=OU_ADDR1

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

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

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

person Dimitre Novatchev    schedule 13.04.2011