I've the below XML document.
<root>
<toc-subitem><toc-title>(C) One year’s separation with consent (s 11A(c))</toc-title> <toc-pg>1.055</toc-pg>
<toc-subitem><toc-title>(I) Rescission of decree <content-style font-style="italic">nisi</content-style></toc-title>
<toc-pg>1.062</toc-pg></toc-subitem></toc-subitem>
</root>
Here I'm trying to differentiate between roman numerals and capital letters using below XSLT Template.
<xsl:template name="get_number_type">
<xsl:param name="number_string"/>
<xsl:analyze-string select="$number_string" regex="([0-9]+\.)|(\([a-h]\))|(\([ivx]+\))|(\([A-Z]+\))|(\([IVXL]+\))">
<xsl:matching-substring>
<xsl:choose>
<xsl:when test="regex-group(1) != ''">
<xsl:text>1</xsl:text>
</xsl:when>
<xsl:when test="regex-group(2) != ''">
<xsl:text>2</xsl:text>
</xsl:when>
<xsl:when test="regex-group(3) != ''">
<xsl:text>3</xsl:text>
</xsl:when>
<xsl:when test="regex-group(4) != ''">
<xsl:text>4</xsl:text>
</xsl:when>
<xsl:when test="regex-group(5) != ''">
<xsl:text>5</xsl:text>
</xsl:when>
</xsl:choose>
</xsl:matching-substring>
<xsl:non-matching-substring>
</xsl:non-matching-substring>
</xsl:analyze-string>
The param value is substring-before(./toc-title,' ')/>
The expected output is 4 for (C) and 5 for (I) where in my case it is showing 4 for both the cases.
Please let me know how can I differentiate these two cases.
Thanks.
While testing for [ABD-HJ-WYZ] is a perfectly adequate solution, you could instead use character class subtraction.
For example, with input document ...
<root>
<toc-subitem><toc-title>(C) One year’s separation with consent (s 11A(c))</toc-title> <toc-pg>1.055</toc-pg>
<toc-subitem><toc-title>(I) Rescission of decree <content-style font-style="italic">nisi</content-style></toc-title>
<toc-pg>1.062</toc-pg></toc-subitem></toc-subitem>
</root>
... this XSLT 2.0 stylesheet ...**
<xsl:transform
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:so="http://stackoverflow.com/questions/24448301"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
version="2.0"
exclude-result-prefixes="so xs">
<xsl:output omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:function name="so:group" as="xs:integer?">
<xsl:param name="number_string" as="xs:string" />
<xsl:analyze-string select="$number_string"
regex="([0-9]+\.) |
(\([a-h]\)) |
(\([ivx]+\)) |
(\(([A-Z-[IVXL]])+\)) |
(\([IVXL]+\)) "
flags="x">
<xsl:matching-substring>
<xsl:choose>
<xsl:when test="regex-group(1)">
<xsl:sequence select="1"/>
</xsl:when>
<xsl:when test="regex-group(2)">
<xsl:sequence select="2"/>
</xsl:when>
<xsl:when test="regex-group(3)">
<xsl:sequence select="3"/>
</xsl:when>
<xsl:when test="regex-group(4)">
<xsl:sequence select="4"/>
</xsl:when>
<xsl:when test="regex-group(6)">
<xsl:sequence select="5"/>
</xsl:when>
</xsl:choose>
</xsl:matching-substring>
</xsl:analyze-string>
</xsl:function>
<xsl:template match="toc-subitem">
<xsl:copy>
<xsl:apply-templates select="#*"/>
<xsl:attribute name="regex-group">
<xsl:value-of select="so:group(substring-before(.,' '))" />
</xsl:attribute>
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
</xsl:transform>
... will yield output ...
<root>
<toc-subitem regex-group="4">
<toc-title>(C) One year’s separation with consent (s 11A(c))</toc-title>
<toc-pg>1.055</toc-pg>
<toc-subitem regex-group="5">
<toc-title>(I) Rescission of decree <content-style font-style="italic">nisi</content-style>
</toc-title>
<toc-pg>1.062</toc-pg>
</toc-subitem>
</toc-subitem>
</root>
Related
Experts, i need to write XSLT 1.0 code to remove the quotes for multiple conditions.
CASE1: Remove the double quotes
CASE2: Remove the double quotes + delete the PIPE symbol inside that double quotes (IF exist)
CASE3: Remove Single quote " from the input field.
Input:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<ns0:Accounting xmlns:ns0="http://sample.com">
<Record>
<DRCR>"DR"</DRCR>
<GLREFERENCE>"TEST|CASE"</GLREFERENCE>
<GLVALUEDATE>EXAM"PLE</GLVALUEDATE>
<GLACCOUNTNUMBER>"1160</GLACCOUNTNUMBER>
<GLEXAMPLE>123</GLEXAMPLE>
<GLEXAMPLE1>EXTRACT|2021-06-16|2853|1308026.7500|1176</GLEXAMPLE1>
</Record>
</ns0:Accounting>
** Desired Output:**
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<ns0:Accounting xmlns:ns0="http://sample.com">
<Record>
<DRCR>DR</DRCR>
<GLREFERENCE>TEST CASE</GLREFERENCE>
<GLVALUEDATE>EXAMPLE</GLVALUEDATE>
<GLACCOUNTNUMBER>1160</GLACCOUNTNUMBER>
<GLEXAMPLE>123</GLEXAMPLE>
<GLEXAMPLE1>EXTRACT|2021-06-16|2853|1308026.7500|1176</GLEXAMPLE1>
</Record>
</ns0:Accounting>
** XSLT I tried:**
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="text()">
<xsl:call-template name="process">
<xsl:with-param name="text" select="."/>
</xsl:call-template>
</xsl:template>
<xsl:template name="process">
<xsl:param name="text"/>
<xsl:choose>
<xsl:when test="contains($text, '"')">
<xsl:value-of select="substring-before($text, '"')"/>
<xsl:value-of select="translate(substring-before(substring-after($text, '"'), '"'), '|', '')"/>
<xsl:call-template name="process">
<xsl:with-param name="text" select="substring-after(substring-after($text, '"'), '"')"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$text"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
This XSLT not handling case 3, which has single quote in the input field. Please assist here..
Maybe something like this could work for you:
XSLT 1.0 (+ EXSLT node-set function)
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="text()">
<xsl:choose>
<xsl:when test="contains(., '"')">
<xsl:variable name="tokens">
<xsl:call-template name="tokenize">
<xsl:with-param name="text" select="."/>
</xsl:call-template>
</xsl:variable>
<xsl:for-each select="exsl:node-set($tokens)/token">
<xsl:choose>
<xsl:when test="(position()=1 or position()=last()) and last() > 1">
<xsl:value-of select="."/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="translate(., '|', '')"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="tokenize">
<xsl:param name="text"/>
<xsl:param name="delimiter" select="'"'"/>
<xsl:variable name="token" select="substring-before(concat($text, $delimiter), $delimiter)" />
<xsl:if test="$token">
<token>
<xsl:value-of select="$token"/>
</token>
</xsl:if>
<xsl:if test="contains($text, $delimiter)">
<!-- recursive call -->
<xsl:call-template name="tokenize">
<xsl:with-param name="text" select="substring-after($text, $delimiter)"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
Note that this does not check the parity of the quotation marks. Any vertical bar character that is both preceded and followed by a quotation mark will be removed. For example, an input of:
<EXAMPLE>abc|123"def|456"ghi|789"jkl|012</EXAMPLE>
will be transformed to:
<EXAMPLE>abc|123def456ghi789jkl|012</EXAMPLE>
I have a XML file containing a list of headings that I need to change to title case (words should begin with a capital letter except for most articles, conjunctions, and prepositions) with the help of XSLT.
Example:
"<h1>PERSONS OF THE DIALOGUE</h1>
in to
"<h1>Persons of the Dialogue</h1>
Please help...
Thanks
Here's a way you could do this:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:output method="xml" indent="yes"/>
<xsl:variable name="words" select="'*a*,*an*,*the*,*and*,*but*,*for*,*nor*,*or*,*so*,*yet*,*as*,*at*,*by*,*if*,*in*,*of*,*on*,*to*,*with*,*when*,*where*'"/>
<xsl:template match="/">
<result>
<xsl:apply-templates select="document/h1"/>
</result>
</xsl:template>
<xsl:template match="h1">
<xsl:copy>
<xsl:variable name="elements" select="tokenize(lower-case(.), ' ')"/>
<xsl:for-each select="$elements">
<xsl:choose>
<!-- The first letter of the first word of a title is always Uppercase -->
<xsl:when test="position()=1">
<xsl:value-of select="upper-case(substring(.,1,1))"/>
<xsl:value-of select="substring(.,2)"/>
<xsl:if test="position()!=last()">
<xsl:text> </xsl:text>
</xsl:if>
</xsl:when>
<xsl:otherwise>
<xsl:choose>
<!-- If the word is contained in $words, leave it Lowercase -->
<xsl:when test="contains($words,concat('*',.,'*'))">
<xsl:value-of select="."/>
<xsl:if test="position()!=last()">
<xsl:text> </xsl:text>
</xsl:if>
</xsl:when>
<!-- If not, first letter is Uppercase -->
<xsl:otherwise>
<xsl:value-of select="upper-case(substring(.,1,1))"/>
<xsl:value-of select="substring(.,2)"/>
<xsl:if test="position()!=last()">
<xsl:text> </xsl:text>
</xsl:if>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
See it working here: https://xsltfiddle.liberty-development.net/93dFK9m/1
Input XML:
<root>
<number>4</number>
<format>start1</format>
<!--this could be start0/start1/alpha -->
</root>
My output should be:
If format=start1 Print 1,2,3,4
If format=start0 Print 0,1,2,3
If format=alpha Print A,B,C,D
number of sequential items is equal to value of "number" node
XSLT stub:
<xsl:template match="/">
<xsl:variable name="mynumber" select="number"></xsl:variable>
<xsl:variable name="mysequence">
<xsl:choose>
<xsl:when test="format='start0'">
<xsl:for-each select="$mynumber">
<!--0,1,2,3-->
</xsl:for-each>
</xsl:when>
<xsl:when test="format='start1'">
<xsl:for-each select="$mynumber">
<!--1,2,3,4-->
</xsl:for-each>
</xsl:when>
<xsl:when test="format='alpha'">
<xsl:for-each select="$mynumber">
<!--A, B, C, D-->
</xsl:for-each>
</xsl:when>
</xsl:choose>
</xsl:variable>
<xsl:value-of select="$mysequence"></xsl:value-of>
</xsl:template>
Consider the following example:
XML
<root>
<item>
<number>4</number>
<format>start0</format>
</item>
<item>
<number>4</number>
<format>start1</format>
</item>
<item>
<number>4</number>
<format>alpha</format>
</item>
</root>
XSLT 2.0
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="item">
<sequence>
<xsl:choose>
<xsl:when test="format='start0'">
<xsl:value-of select="for $i in 1 to number return $i - 1" separator=", "/>
</xsl:when>
<xsl:when test="format='start1'">
<xsl:value-of select="for $i in 1 to number return $i" separator=", "/>
</xsl:when>
<xsl:when test="format='alpha'">
<xsl:value-of select="for $i in 1 to number return codepoints-to-string($i + 64)" separator=", "/>
</xsl:when>
</xsl:choose>
</sequence>
</xsl:template>
</xsl:stylesheet>
Result
<?xml version="1.0" encoding="UTF-8"?>
<root>
<sequence>0, 1, 2, 3</sequence>
<sequence>1, 2, 3, 4</sequence>
<sequence>A, B, C, D</sequence>
</root>
Note that this assumes number will not exceed 26 (at least not when the format is "alpha"); otherwise you will need to use xsl:number to format it as alpha, as shown in the answer by #potame - except it could be more concise:
<xsl:template match="item">
<xsl:variable name="fmt" select="format" />
<sequence>
<xsl:for-each select="1 to number">
<xsl:number value="if ($fmt='start0') then . - 1 else ." format="{if ($fmt='alpha') then 'A' else '0'}"/>
<xsl:if test="position()!=last()">
<xsl:text>, </xsl:text>
</xsl:if>
</xsl:for-each>
</sequence>
</xsl:template>
Here's a possible solution, thanks to the use of an XPath sequence, e.g. select="1 to 10":
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output method="html" doctype-public="XSLT-compat"
omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />
<xsl:template match="root">
<xsl:variable name="mynumber" select="number" as="xs:integer" />
<xsl:variable name="mysequence">
<xsl:choose>
<xsl:when test="format='start0'">
<xsl:for-each select="0 to ($mynumber - 1)">
<!--0,1,2,3-->
<xsl:value-of select="."/>
</xsl:for-each>
</xsl:when>
<xsl:when test="format='start1'">
<xsl:for-each select="1 to $mynumber">
<!--0,1,2,3-->
<xsl:value-of select="."/>
</xsl:for-each>
</xsl:when>
<xsl:when test="format='alpha'">
<xsl:for-each select="1 to $mynumber">
<xsl:number value="." format="A"/>
</xsl:for-each>
</xsl:when>
</xsl:choose>
</xsl:variable>
<xsl:value-of select="$mysequence"/>
</xsl:template>
</xsl:transform>
I have an xml schema that has a structure like
<Level>
<Level1>...data...</Level1>
<Level2>...data...</Level2>
.
.
.
</Level>
I want to remove the <Level> tag. How am I supposed to do that, with the help of xslt.
The standard answer to any "how do I keep most of my XML the same but tweak some little bits of it" question is "use an identity template and then override it for the specific things you want to change"
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<!-- omit the <?xml?> line in the output, it won't be well-formed anyway -->
<xsl:output method="xml" omit-xml-declaration="yes" />
<xsl:template match="#*|node()">
<xsl:copy><xsl:apply-templates select="#*|node()" /></xsl:copy>
</xsl:template>
<xsl:template match="/*">
<xsl:apply-templates select="node()" />
</xsl:template>
</xsl:stylesheet>
but as Mr Lister points out in the comments, this will leave you with something that is not well formed XML, as it will have more than one document element.
When I apply this stylesheet on the input XML
<Level>
<Level1>...data...</Level1>
<Level2>...data...</Level2>
</Level>
it produces the result
<Level1>...data...</Level1>
<Level2>...data...</Level2>
If you want to store all child elements of the document element in a variable, you can do something like:
<xsl:variable name="myVar" select="/*/*"/>
If, however, you want to the stylesheet to produce a string, this might be a solution:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="text"/>
<xsl:template match="/*">
<xsl:apply-templates select="node()"/>
</xsl:template>
<xsl:template match="*">
<!-- We write the opening tag -->
<xsl:value-of select="concat('<',local-name())"/>
<!-- Now, all attributes -->
<xsl:apply-templates select="#*"/>
<!-- Depending on whether we have an empty element or not,
we're adding the content or closing it immediately -->
<xsl:choose>
<xsl:when test="node()">
<!-- Close opening tag -->
<xsl:value-of select="'>'"/>
<!-- Add the content -->
<xsl:apply-templates select="node()"/>
<!-- Write closing tag -->
<xsl:value-of select="concat('</',local-name(),'>')"/>
</xsl:when>
<xsl:otherwise>
<!-- Create empty element by closing tag immediately -->
<xsl:value-of select="'/>'"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="#*">
<!-- Write an attribute -->
<xsl:value-of select="concat(' ',local-name(),'="',.,'"')"/>
</xsl:template>
</xsl:stylesheet>
It produces text (and therefore you won't get non-well-formed XML). It's a little over-simplified because it does not handle namespaces, comments, processing instructions and quotes in attributes. If your input XML contains any of these, you'd have to refine the stylesheet.
I have created a new XSLT definition which fulfill my requremtn with the help of your code
<?xml version="1.0" encoding="UTF-8"?><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output encoding="utf-8" method="text" omit-xml-declaration="yes"/>
<xsl:variable name="nl">
<xsl:text/>
</xsl:variable>
<xsl:variable name="tb">
<xsl:text/>
</xsl:variable>
<xsl:template match="/*">
<!-- Open the root array -->
<xsl:text>[{</xsl:text>
<xsl:value-of select="$nl"/>
<!-- Process all the child nodes of the root -->
<xsl:apply-templates mode="detect" select="*">
<xsl:with-param name="indent" select="$tb"/>
</xsl:apply-templates>
<!-- Close the root array -->
<xsl:value-of select="$nl"/>
<xsl:text>}]</xsl:text>
</xsl:template>
<xsl:template match="*" mode="detect">
<xsl:choose>
<xsl:when test="name(preceding-sibling::*[1]) = name(current()) and name(following-sibling::*[1]) != name(current())">
<xsl:apply-templates mode="obj-content" select="."/>
<xsl:text>]</xsl:text>
<xsl:if test="count(following-sibling::*[name() != name(current())]) > 0">, </xsl:if>
</xsl:when>
<xsl:when test="name(preceding-sibling::*[1]) = name(current())">
<xsl:apply-templates mode="obj-content" select="."/>
<xsl:if test="name(following-sibling::*) = name(current())">, </xsl:if>
</xsl:when>
<xsl:when test="following-sibling::*[1][name() = name(current())]">
<xsl:text>"</xsl:text>
<xsl:value-of select="name()"/>
<xsl:text>" : [</xsl:text>
<xsl:apply-templates mode="obj-content" select="."/>
<xsl:text>, </xsl:text>
</xsl:when>
<xsl:when test="count(./child::*) > 0 or count(#*) > 0">
<xsl:text>"</xsl:text>
<xsl:value-of select="name()"/>" : [<xsl:apply-templates
mode="obj-content" select="."/>
<xsl:if test="count(following-sibling::*) > 0">], </xsl:if>
</xsl:when>
<xsl:when test="count(./child::*) = 0">
<xsl:text>"</xsl:text>
<xsl:value-of select="name()"/>" : "<xsl:apply-templates select="."/>
<xsl:text>"</xsl:text>
<xsl:if test="count(following-sibling::*) > 0">, </xsl:if>
</xsl:when>
</xsl:choose>
</xsl:template>
<xsl:template match="*" mode="obj-content">
<xsl:text>{</xsl:text>
<xsl:apply-templates mode="attr" select="#*"/>
<xsl:if test="count(#*) > 0 and (count(child::*) > 0 or text())">, </xsl:if>
<xsl:apply-templates mode="detect" select="./*"/>
<xsl:if test="count(child::*) = 0 and text() and not(#*)">
<xsl:text>"</xsl:text>
<xsl:value-of select="name()"/>" : "<xsl:value-of select="text()"/>
<xsl:text>"</xsl:text>
</xsl:if>
<xsl:if test="count(child::*) = 0 and text() and #*">
<xsl:text>: "</xsl:text>
<xsl:value-of select="text()"/>
<xsl:text>"</xsl:text>
</xsl:if>
<xsl:text>}</xsl:text>
<xsl:if test="position() < last()">, </xsl:if>
</xsl:template>
<xsl:template match="#*" mode="attr">
<xsl:text>"</xsl:text>
<xsl:value-of select="name()"/>" : "<xsl:value-of select="."/>
<xsl:text>"</xsl:text>
<xsl:if test="position() < last()">,</xsl:if>
</xsl:template>
<xsl:template match="node/#TEXT | text()" name="removeBreaks">
<xsl:param name="pText" select="normalize-space(.)"/>
<xsl:choose>
<xsl:when test="not(contains($pText, '
'))">
<xsl:copy-of select="$pText"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat(substring-before($pText, '
'), ' ')"/>
<xsl:call-template name="removeBreaks">
<xsl:with-param name="pText" select="substring-after($pText, '
')"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
I have split one string key6='||1-LIW-3324|1-LIW-3325|1-LIW-3326|1-LIW-3327|1-LIW-4232' with separator '|' thru one template named StringSplit.
I have called this StringSplit template from another template. So each split value is stored in SeparatedLineItems.
Now I want to refer each split node(SeparatedLineItems) in the calling template and want to compare each separated/split node with another variable . How can i do it.
Here is the code.
<xsl:template match="/">
<xsl:variable name="check3">
<xsl:value-of select="1-LIW-3"/>
</xsl:variable>
<myProj>
<xsl:call-template name="StringSplit">
<xsl:with-param name="val" select="$key6"/>
</xsl:call-template>
<!--here I want to compare "SeperatedLineItems" with $check3 -->
<!--<xsl:variable name="con">
<xsl:value-of select="contains($key6,$check3)"/>
</xsl:variable>-->
</myProj>
</xsl:template>
<xsl:template name="StringSplit">
<xsl:param name="val" select="$key6"/>
<!-- do a check to see if the input string (still) has a "|" in it -->
<xsl:choose>
<xsl:when test="contains($val, '|')">
<!-- pull out the value of the string before the "|" delimiter -->
<SeperatedLineItems>
<xsl:value-of select="substring-before($val, '|')"/>
</SeperatedLineItems>
<!-- recursively call this template and pass in value AFTER the "|" delimiter -->
<xsl:call-template name="StringSplit">
<xsl:with-param name="val" select="substring-after($val, '|')"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<!-- if there is no more delimiter values, print out the whole string -->
<SeperatedLineItems>
<xsl:value-of select="$val"/>
</SeperatedLineItems>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
This XSLT 1.0 style-sheet demonstrates how to access the elements returned by calling a template ...
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
exclude-result-prefixes="xsl msxsl">
<xsl:output method="text"/>
<xsl:variable name="key6" select="'||1-LIW-3324|1-LIW-3325|1-LIW-3326|1-LIW-3327|1-LIW-4232'" />
<xsl:template match="/">
Does my $key6 variable contain precisely '1-LIW-3'?
<xsl:variable name="keys">
<xsl:call-template name="StringSplit">
<xsl:with-param name="val" select="$key6"/>
</xsl:call-template>
</xsl:variable>
<xsl:choose>
<xsl:when test="msxsl:node-set($keys)/*[. = '1-LIW-3']">
YES
</xsl:when>
<xsl:otherwise>
NO
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="StringSplit">
<xsl:param name="val" />
<xsl:choose>
<xsl:when test="contains($val,'|')">
<SeperatedLineItems>
<xsl:value-of select="substring-before($val,'|')" />
</SeperatedLineItems>
<xsl:variable name="remainder">
<xsl:call-template name="StringSplit">
<xsl:with-param name="val" select="substring-after($val,'|')" />
</xsl:call-template>
</xsl:variable>
<xsl:copy-of select="msxsl:node-set($remainder)/*" />
</xsl:when>
<xsl:when test="$val != ''">
<SeperatedLineItems>
<xsl:value-of select="$val" />
</SeperatedLineItems>
</xsl:when>
<xsl:otherwise>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
To which the result is...
Does my $key6 variable contain '1-LIW-3'?
NO
And here is the XSLT 2.0 equivalent...
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xsl xs">
<xsl:output method="text"/>
<xsl:variable name="key6" select="'||1-LIW-3324|1-LIW-3325|1-LIW-3326|1-LIW-3327|1-LIW-4232'" />
<xsl:template match="/">
Does my $key6 variable contain precisely '1-LIW-3'?
<xsl:variable name="keys" select="tokenize($key6,'\|')" as="xs:string*" />
<xsl:choose>
<xsl:when test="some $key in $keys satisfies ($key = '1-LIW-3')">
YES
</xsl:when>
<xsl:otherwise>
NO
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
The above makes the $keys variable a sequence of strings rather than elements containing strings. If you prefer elements, then you could use the following alternative. Although this alternative suffers from the disadvantage that it does not include the empty string items.
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xsl xs">
<xsl:output method="text"/>
<xsl:variable name="key6" select="'||1-LIW-3324|1-LIW-3325|1-LIW-3326|1-LIW-3327|1-LIW-4232'" />
<xsl:template match="/">
Does my $key6 variable contain precisely '1-LIW-3'?
<xsl:variable name="keys" as="element()*" >
<xsl:analyze-string select="concat($key6,'|')" regex="([^\|]*)\|">
<xsl:matching-substring>
<SeperatedLineItems>
<xsl:value-of select="regex-group(1)" />
</SeperatedLineItems>
</xsl:matching-substring>
</xsl:analyze-string>
</xsl:variable>
<xsl:choose>
<xsl:when test="$keys[. = '1-LIW-3']">
YES
</xsl:when>
<xsl:otherwise>
NO
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>