Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to compare against multiple strings in xslt

Tags:

xml

xslt

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

<xsl:if test="/Lines/@name = 'John' or /Lines/@name = 'Steve' or /Lines/@name = 'Marc' " >

Can any one tell me, instead of using 'or' in the above case, how can I check whether a string is existing in an set of strings using xslt.

Thanks.

like image 407
Bhaskar Avatar asked Jun 15 '11 11:06

Bhaskar


People also ask

How do you compare in XSLT?

Answer. There is no direct way to compare the dates in XSLT, but the number function we can convert the date into a number and then can perform the comparison in an 'IF' condition. The following function helps to convert the date into number and then can use the >= operator to check the date in an 'IF' condition.

What is current group () in XSLT?

Returns the contents of the current group selected by xsl:for-each-group. Available in XSLT 2.0 and later versions. Available in all Saxon editions. current-group() ➔ item()*

Does XSLT use XPath?

XSLT uses XPath to find information in an XML document. XPath is used to navigate through elements and attributes in XML documents. In the transformation process, XSLT uses XPath to define parts of the source document that should match one or more predefined templates.

What is text () in XSLT?

XSLT <xsl:text> The <xsl:text> element is used to write literal text to the output. Tip: This element may contain literal text, entity references, and #PCDATA.


3 Answers

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>
like image 71
Dimitre Novatchev Avatar answered Oct 18 '22 21:10

Dimitre Novatchev


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>
like image 29
Martin Honnen Avatar answered Oct 18 '22 20:10

Martin Honnen


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 ...
like image 4
MikeyKennethR Avatar answered Oct 18 '22 22:10

MikeyKennethR