Nested conditional if else statements in xpath

前端 未结 4 991
迷失自我
迷失自我 2020-12-31 15:12

I have this XML:


    No
    Yes
    
           


        
相关标签:
4条回答
  • 2020-12-31 15:20

    I. In XPath 2.0 one simply translates this to:

       if(/*/propertyTypes/propertyType = 'RESIDENTIAL')
        then
         (if(/*/leasehold='Yes')
           then 'Rent'
           else 'Buy'
         )
         else
           if(/*/leasehold='Yes')
             then 'Leasehold'
             else 'Freehold'
    

    XSLT 2.0 - based verification:

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

    When this transformation is applied on the provided XML document:

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

    the XPath expression is evaluated and the result of this evaluation is copied to the output:

    Buy
    

    II. XPath 1.0 solution

    In XPath 1.0 there isn't an if operator.

    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.

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

    One of the main achivements of this formula is that it works for strings of any length and no lengths need to be specified.

    Explanation:

    Here we use the fact that by definition:

    number(true()) = 1
    

    and

    number(false()) = 0
    

    and that

    1 div 0 = Infinity
    

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

     substring($stringA, Infinity)
    

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

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

    sibstring($stringA, 1) 
    

    that is just $stringA.

    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'
                                          ]
                                      )
                          )
                   )
    

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

    XSLT 1.0 - based verification:

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

    When this transformation is applied on the provided XML document (above), the XPath expression is evaluated and the result of this evaluation is copied to the output:

    buy
    

    Do note:

    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.

    0 讨论(0)
  • 2020-12-31 15:31

    Becker's method for your data is the following:

    concat(substring('Rent',      1 div boolean(propertyTypes/propertyType ="RESIDENTIAL" and leasehold="Yes")),
           substring('Buy',       1 div boolean(propertyTypes/propertyType ="RESIDENTIAL" and leasehold="No")),
           substring('Leasehold', 1 div boolean(propertyTypes/propertyType!="RESIDENTIAL" and leasehold="Yes")),
           substring('Freehold',  1 div boolean(propertyTypes/propertyType!="RESIDENTIAL" and leasehold="No")))
    
    0 讨论(0)
  • 2020-12-31 15:36

    Spent all day today, but works for me this is for Xpath 1.0:

    concat(
    substring(properties/property[@name="Headline"], 1, string-length(properties/property[@name="Headline"]) * 1), 
    substring(properties/property[@name="Name"], 1, not(number(string-length(properties/property[@name="Headline"]))) * string-length(properties/property[@name="Name"]))
    )
    
    0 讨论(0)
  • 2020-12-31 15:39

    Try this

    if (condition) 
    then 
      if (condition) stmnt 
      else stmnt 
    else 
      if (condition) stmnt 
      else stmnt 
    
    0 讨论(0)
提交回复
热议问题