xpath 中的嵌套条件 if else 语句 [英] Nested conditional if else statements in xpath

查看:24
本文介绍了xpath 中的嵌套条件 if else 语句的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个 XML:

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

我想创建一个与以下嵌套 if-else 伪代码块相同的 xpath 语句.

and I want to create an xpath statement that is same as the following nested if-else pseudocode block.

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

我已经看到了有关 Becker 方法的一些信息,但我无法真正遵循它.XPath 真的不是我的强项.

I've seen something about Becker's method but I couldn't really follow it. XPath isn't my strong point really.

推荐答案

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 运算符.

In XPath 1.0 there isn't an if operator.

条件语句仍然可以使用单个 XPath 1.0 表达式来实现,但这更加棘手,并且表达式可能不太可读和易于理解.

A conditional statement can still be implemented with a single XPath 1.0 expression, but this is more tricky and the expression may not be too readable and understandable.

当条件 $condtrue() 和否则产生 $stringB:

Here is a generic way (first proposed by Jeni Tennison) to produce $stringA when a condition $cond is true() and otherwise produce $stringB:

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

这个公式的主要成就之一是它适用于任何长度的字符串,并且不需要指定长度.

解释:

这里我们使用的事实是,根据定义:

Here we use the fact that by definition:

number(true()) = 1

number(false()) = 0

还有那个

1 div 0 = Infinity

所以,如果$condfalse,则上面concat()的第一个参数为:

So, if $cond is false, the first argument of concat() above is:

 substring($stringA, Infinity)

这是空字符串,因为 $stringA 的长度是有限的.

and this is the empty string, because $stringA has a finite length.

另一方面,如果 $condtrue() 那么上面 concat() 的第一个参数是:

On the other side, if $cond is true() then the first argument of concat() above is:

sibstring($stringA, 1) 

这只是 $stringA.

因此,根据 $cond 的值,上面 concat() 的两个参数中只有一个是非空字符串(分别为 $stringA$stringB).

So, depending on the value of $cond only one of the two arguments of concat() above is a nonempty string (respectively $stringA or $stringB).

将这个通用公式应用于具体问题,我们可以将大条件表达式的前半部分翻译成:

Applying this generic formula to the specific question, we can translate the first half of the big conditional expression into:

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 表达式.

This should give you an idea how to translate the whole conditional expression into a single XPath 1.0 expression.

基于 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 表达式中替换这些字符串,而不必担心指定任何长度.

If you decide to replace the specific strings with other strings that have different lengths than the original, you simply replace these strings in the above XPath 1.0 expression and you don't have to worry about specifying any lengths.

这篇关于xpath 中的嵌套条件 if else 语句的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆