xpath中嵌套的条件if else语句

Kir*_*WSI 9 xpath conditional if-statement xpath-2.0

我有这个XML:

<property id="1011">
    <leasehold>No</leasehold>
    <freehold>Yes</freehold>
    <propertyTypes>
        <propertyType>RESIDENTIAL</propertyType>
    </propertyTypes>
</property>
Run Code Online (Sandbox Code Playgroud)

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

if( propertyTypes/propertyType == 'RESIDENTIAL') {
    if( leasehold == 'Yes' ){
        return 'Rent'
    } else
        return 'Buy'
    }
} else {
    if( leasehold == 'Yes' ){
        return 'Leasehold'
    } else
        return 'Freehold'
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Dim*_*hev 21

I.在XPath 2.0中,只需将其转换为:

   if(/*/propertyTypes/propertyType = 'RESIDENTIAL')
    then
     (if(/*/leasehold='Yes')
       then 'Rent'
       else 'Buy'
     )
     else
       if(/*/leasehold='Yes')
         then 'Leasehold'
         else 'Freehold'
Run Code Online (Sandbox Code Playgroud)

基于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>
Run Code Online (Sandbox Code Playgroud)

在提供的XML文档上应用此转换时:

<property id="1011">
    <leasehold>No</leasehold>
    <freehold>Yes</freehold>
    <propertyTypes>
        <propertyType>RESIDENTIAL</propertyType>
    </propertyTypes>
</property>
Run Code Online (Sandbox Code Playgroud)

评估XPath表达式,并将此评估的结果复制到输出:

Buy
Run Code Online (Sandbox Code Playgroud)

II.XPath 1.0解决方案

在XPath 1.0中没有if运算符.

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

这里是一个通用的方法(首先由杰尼·坦尼森提议)产生$stringA时的条件$condtrue()和其他方式生产$stringB:

concat(substring($stringA, 1 div $cond), substring($stringB, 1 div not($cond)))
Run Code Online (Sandbox Code Playgroud)

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

说明:

在这里我们使用的事实是:

number(true()) = 1
Run Code Online (Sandbox Code Playgroud)

number(false()) = 0
Run Code Online (Sandbox Code Playgroud)

然后

1 div 0 = Infinity
Run Code Online (Sandbox Code Playgroud)

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

 substring($stringA, Infinity)
Run Code Online (Sandbox Code Playgroud)

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

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

sibstring($stringA, 1) 
Run Code Online (Sandbox Code Playgroud)

就是这样$stringA.

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

将此通用公式应用于特定问题,我们可以将大条件表达式的前半部分转换为:

concat(
           substring('rent',
                      1 div boolean(/*[leasehold='Yes'
                                     and
                                       propertyTypes/propertyType = 'RESIDENTIAL'
                                      ]
                                  )
                      ),
           substring('buy',
                      1 div not(/*[leasehold='Yes'
                                     and
                                       propertyTypes/propertyType = 'RESIDENTIAL'
                                      ]
                                  )
                      )
               )
Run Code Online (Sandbox Code Playgroud)

这应该可以让您了解如何将整个条件表达式转换为单个XPath 1.0表达式.

基于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>
Run Code Online (Sandbox Code Playgroud)

当在提供的XML文档(上面)上应用此转换时,将评估XPath表达式,并将此求值的结果复制到输出:

buy
Run Code Online (Sandbox Code Playgroud)

请注意:

如果您决定使用长度与原始字符串不同的其他字符串替换特定字符串,则只需在上面的XPath 1.0表达式中替换这些字符串,您就不必担心指定任何长度.