要比较XSLT中的两个元素(字符串类型)?

时间:2011-04-13 12:31:55

标签: 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 个答案:

答案 0 :(得分:33)

首先,提供长代码

    <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_ADDR1'时,

才会计算OU_NAME

这显然不是你想要的!

很可能你想要:

OU_NAME=OU_ADDR1

此表达式的计算结果为true,当前节点至少有一个OU_NAME子节点,当前节点的一个OU_ADDR1子节点具有相同的字符串值。

最后,在XPath 2.0中,还可以使用值比较运算符ltleeqgt来比较字符串, ge和继承自XPath 1.0的一般比较运算符=

当一个或两个参数是多个项目的序列时,尝试评估值比较运算符会导致错误。