How to compare against multiple strings in xslt

后端 未结 6 442
滥情空心
滥情空心 2020-12-10 12:45

For comparing an xml string value against multiple strings, I am doing the following.



        
相关标签:
6条回答
  • 2020-12-10 12:53

    For space-separated words you can use index-of(tokenize("list of allowed", "\s+"), "needle")) or match to go with regular expressions, although I am pretty sure there is something smarter than this.

    0 讨论(0)
  • 2020-12-10 12:57

    XPath has a some $x in (1,2,..) satisfies $x>10 expression that could be useful for this. See: http://www.java2s.com/Code/XML/XSLT-stylesheet/everyandsomeoperator.htm

    0 讨论(0)
  • 2020-12-10 13:05

    XSLT 2.0 only: <xsl:if test="/Lines/@name = ('John', 'Steve', 'Marc')">

    With XSLT 1.0 you can't write a literal expression representing a sequence of strings or a set of strings but if you know the literal values then you can construct a set of nodes e.g.

    <xsl:stylesheet
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      version="1.0"
      xmlns:data="http://example.com/data"
      exclude-result-prefixes="data">
    
      <data:data xmlns="">
        <value>John</value>
        <value>Steve</value>
        <value>Marc</value>
      </data:data>
    
      <xsl:variable name="values" select="document('')/xsl:stylesheet/data:data/value"/>
    
      <xsl:template match="...">
         <xsl:if test="/Lines/@name = $values">..</xsl:if>
      </xsl:template>
    
    </xsl:stylesheet>
    
    0 讨论(0)
  • 2020-12-10 13:12

    Three ways of doing this:

    1. Use a pipe (or other appropriate character) delimited string

    ...

     <xsl:template match=
      "Lines[contains('|John|Steve|Mark|',
                      concat('|', @name, '|')
                     )
             ]
      ">
         <!-- Appropriate processing here -->
     </xsl:template>
    

    .2. Test against an externally passed parameter. If the parameter is not externally set, and we are using XSLT 1.0, the xxx:node-set() extension function needs to be used to convert it to normal node-set, before accessing its children

    <xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     <xsl:output omit-xml-declaration="yes" indent="yes"/>
     <xsl:strip-space elements="*"/>
    
     <!-- externally-specified parameter -->
     <xsl:param name="pNames">
      <n>John</n>
      <n>Steve</n>
      <n>Mark</n>
     </xsl:param>
    
     <xsl:template match="Lines">
      <xsl:if test="@name = $pNames/*">
         <!-- Appropriate processing here -->
        </xsl:if>
     </xsl:template>
    </xsl:stylesheet>
    

    .3. In XSLT 2.0 compare against a sequence of strings

     <xsl:template match="Lines[@name=('John','Steve','Mark')]">
         <!-- Appropriate processing here -->
     </xsl:template>
    
    0 讨论(0)
  • 2020-12-10 13:16

    Yep - I use substring - put all your name in a string - xsl:variable - then if contains true, the name is there

    e.g.

     <xsl:variable name="months">**janfebmaraprmajjunjulaugsepoktnovdec</xsl:variable>
    
    
     <xsl:if test="contains($months,'feb')"> do stuff ...
    
    0 讨论(0)
  • 2020-12-10 13:17

    Other possiblity:

    XPath 2.0 (XSLT 2.0)

    matches(/Lines/@name, 'John|Steve|Marc')
    

    In XSLT 1.0 you have the similar function matches provided by EXSLT.

    Notice

    This is not exact match against the string, but a regex match, which in your case seems appropriate anyway.

    0 讨论(0)
提交回复
热议问题