Validation AlphaNumeric XSLT - xslt-1.0

I was stuck with validation. i can validation when empty string, and validation with length requirement, and validation with just numeric, But when the input was have a special character and have contains alphanumeric. i was stuck. can anyone helping me correct which side i need fix with my code
MYCODE :
<?xml version="1.0" encoding="UTF-8"?>
<localEntry key="LOCAL_XSLT_Validate" xmlns="http://ws.apache.org/ns/synapse">
<xsl:stylesheet version="1.0" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" method="xml" omit-xml-declaration="yes"/>
<xsl:template match="/">
<OperationValueRegex>
<xsl:call-template name="values">
<xsl:with-param name="vals" select="//OperationValueRegex/Value"/>
</xsl:call-template>
</OperationValueRegex>
</xsl:template>
<xsl:template name="values">
<xsl:param name="vals"/>
<xsl:choose>
<!-- Validation Number -->
<xsl:when test="fn:tokenize($vals, ' ')[matches(., '\d+')] and string-length($vals) = 8">
<Result1>
<xsl:value-of select="$vals"/>
</Result1>
</xsl:when>
<xsl:when test="$vals = 'NaN' or string-length($vals) != 8">
<Result1>
<Value>
<xsl:value-of select="$vals"/>
</Value>
<notification>input was not valid requirement maximum</notification>
</Result1>
</xsl:when>
<xsl:otherwise>
<Result1>
<Value>
<xsl:value-of select="$vals"/>
</Value>
<notification>Wrong Format</notification>
</Result1>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
</localEntry>
Request and expected result
{
"OperationValueRegex" : {
"Value" : "1234asdv"
}
}
<OperationValueRegex xmlns="http://ws.apache.org/ns/synapse" xmlns:fn="http://www.w3.org/2005/xpath-functions">
<Result1>1234asdv</Result1>
<notification>Wrong Format</notification>
</OperationValueRegex>
Thanks

I can found the way for validation Alphanumeric
<?xml version="1.0" encoding="UTF-8"?>
<localEntry key="LOCAL_XSLT_Validate" xmlns="http://ws.apache.org/ns/synapse">
<xsl:stylesheet version="1.0" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" method="xml" omit-xml-declaration="yes"/>
<xsl:template match="/">
<OperationValueRegex>
<xsl:call-template name="values">
<xsl:with-param name="vals" select="//OperationValueRegex/Value"/>
</xsl:call-template>
<xsl:call-template name="dates">
<xsl:with-param name="dats" select="//OperationValueRegex/Date"/>
</xsl:call-template>
</OperationValueRegex>
</xsl:template>
<xsl:template name="values">
<xsl:param name="vals"/>
<xsl:choose>
<!-- Validation Number -->
<xsl:when test="fn:matches($vals, '^\d+$') and string-length($vals) = 8">
<Result1>
<xsl:value-of select="$vals"/>
</Result1>
</xsl:when>
<xsl:when test="$vals = 'NaN' or string-length($vals) != 8">
<Result1>
<Value>
<xsl:value-of select="$vals"/>
</Value>
<notification>input was not valid requirement maximum</notification>
</Result1>
</xsl:when>
<xsl:when test="fn:matches($vals, '^[a-zA-Z0-9_]*$') and string-length($vals) > 0">
<Value>
<xsl:value-of select="$vals"/>
</Value>
<notification>Wrong Format</notification>
</xsl:when>
</xsl:choose>
</xsl:template>
<xsl:template name="dates">
<xsl:param name="dats"/>
<xsl:variable name="dateString">
<xsl:value-of select="substring($dats,1,4)"/>
<xsl:text>-</xsl:text>
<xsl:value-of select="substring($dats,5,2)"/>
<xsl:text>-</xsl:text>
<xsl:value-of select="substring($dats,7,2)"/>
</xsl:variable>
<RequiredFormat>
<xsl:value-of select="format-date(xs:date($dateString), '[Y]/[M]/[D]')"/>
</RequiredFormat>
<OtherFormat>
<xsl:value-of select="format-date(xs:date($dateString), '[MNn] [D], [Y]')"/>
</OtherFormat>
</xsl:template>
</xsl:stylesheet>
</localEntry>
But I still have trouble with when input was have special character like = "#+./!~`*%^$()-#". Need little more help about this

Related

XSL Replace an element by splitting it's values

I have the following XML which contains the order details in single element.
<?xml version="1.0" encoding="UTF-8"?>
<MESSAGE xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<MESSAGE_ID>361155</MESSAGE_ID>
<NAME>Header123</NAME>
<HEADERS>
<HEADER>
<ACTION_COUNT>1</ACTION_COUNT>
<ACTION_DESC>
<DAILY_LOAD>
<LOAD_NO>1</LOAD_NO>
<CUSTOMER_NO>09656951</CUSTOMER_NO>
<REFERENCE xsi:nil="1"/>
<SERIAL>450255470000403803</SERIAL>
<ORDERS>
<ORDER>
<ITEM>5000128762885</ITEM>
<DETAILS>4582;Robert and Co;8;5526;SWD</DETAILS>
<EMP_NO>13</EMP_NO>
<USE_BY_DATE>20110611</USE_BY_DATE>
<DEPOT>5000128910035</DEPOT>
</ORDER>
<ORDER>
<ITEM>5000128853613</ITEM>
<DETAILS>5000;Anne and Co;9;2020;ATM</DETAILS>
<EMP_NO>5</EMP_NO>
<USE_BY_DATE>20110613</USE_BY_DATE>
<DEPOT>5000128910035</DEPOT>
</ORDER>
</ORDERS>
</DAILY_LOAD>
</ACTION_DESC>
</HEADER>
</HEADERS>
<LIST_ID>23689</LIST_ID>
<TRAILER>TEST_NEEDED</TRAILER>
</MESSAGE>
I need that to be transformed into the following format.
(only the DAILY_LOAD>ORDERS section should be changed as below)
.....
<ORDERS>
<ORDER>
<ITEM>5000128762885</ITEM>
<ORDER_NO>4582</ORDER_NO>
<CUSTOMER>Robert and Co</CUSTOMER>
<NO_OF_ITEMS>8</NO_OF_ITEMS>
<TOTAL>5526</TOTAL>
<LOCATION>SWD</LOCATION>
<EMP_NO>13</EMP_NO>
<USE_BY_DATE>20110611</USE_BY_DATE>
<DEPOT>5000128910035</DEPOT>
</ORDER>
<ORDER>
<ITEM>5000128853613</ITEM>
<ORDER_NO>5000</ORDER_NO>
<CUSTOMER>Anne and Co</CUSTOMER>
<NO_OF_ITEMS>9</NO_OF_ITEMS>
<TOTAL>2020</TOTAL>
<LOCATION>ATM</LOCATION>
<EMP_NO>5</EMP_NO>
<USE_BY_DATE>20110613</USE_BY_DATE>
<DEPOT>5000128910035</DEPOT>
</ORDER>
</ORDERS>
.....
The transformed XML contains no but it's divided into CUSTOMER, NO_OF_ITEMS, TOTAL and LOCATION. Any suggestion or help will be highly appreciated.
Thank you in advance.
XSLT 1.0
Using tokenizeString template as suggested in Heber.it blog. I have modified the code for producing different tag names depending on recursion level (ORDER_NO, CUSTOMER, NO_OF_ITEMS, etc).
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<!-- replaces order nodes -->
<xsl:template match="ORDER">
<ORDER>
<xsl:call-template name="tokenizeString">
<xsl:with-param name="list" select="./DETAILS"/>
<xsl:with-param name="delimiter" select="';'"/>
<xsl:with-param name="level" select="1"/>
</xsl:call-template>
</ORDER>
</xsl:template>
<!-- copy everything that doesn't match another template -->
<xsl:template match="#* | node()">
<xsl:copy>
<xsl:apply-templates select="#* | node()"/>
</xsl:copy>
</xsl:template>
<!-- template to tokenize strings -->
<xsl:template name="tokenizeString">
<!--passed template parameter -->
<xsl:param name="list"/>
<xsl:param name="delimiter"/>
<xsl:param name="level"/>
<xsl:choose>
<xsl:when test="contains($list, $delimiter)">
<xsl:choose>
<xsl:when test="$level = 1">
<ITEM>
<xsl:value-of select="ITEM"/>
</ITEM>
<ORDER_NO>
<xsl:value-of select="substring-before($list,$delimiter)"/>
</ORDER_NO>
</xsl:when>
<xsl:when test="$level = 2">
<CUSTOMER>
<xsl:value-of select="substring-before($list,$delimiter)"/>
</CUSTOMER>
</xsl:when>
<xsl:when test="$level = 3">
<NO_OF_ITEMS>
<xsl:value-of select="substring-before($list,$delimiter)"/>
</NO_OF_ITEMS>
</xsl:when>
<xsl:when test="$level = 4">
<TOTAL>
<xsl:value-of select="substring-before($list,$delimiter)"/>
</TOTAL>
</xsl:when>
</xsl:choose>
<xsl:call-template name="tokenizeString">
<!-- store anything left in another variable -->
<xsl:with-param name="list" select="substring-after($list,$delimiter)"/>
<xsl:with-param name="delimiter" select="$delimiter"/>
<xsl:with-param name="level" select="$level + 1"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="$list = ''">
<xsl:text/>
</xsl:when>
<xsl:otherwise>
<LOCATION>
<xsl:value-of select="$list"/>
</LOCATION>
<EMP_NO>
<xsl:value-of select="EMP_NO"/>
</EMP_NO>
<USE_BY_DATE>
<xsl:value-of select="USE_BY_DATE"/>
</USE_BY_DATE>
<DEPOT>
<xsl:value-of select="DEPOT"/>
</DEPOT>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
XSLT 2.0
Using tokenize function you can do this:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<!-- this template replaces order nodes -->
<xsl:template match="ORDER">
<ORDER>
<xsl:variable name="fields" select="tokenize(DETAILS, ';')"/>
<ITEM>
<xsl:value-of select="ITEM"/>
</ITEM>
<ORDER_NO>
<xsl:value-of select="$fields[position()=1]"/>
</ORDER_NO>
<CUSTOMER>
<xsl:value-of select="$fields[position()=2]"/>
</CUSTOMER>
<NO_OF_ITEMS>
<xsl:value-of select="$fields[position()=3]"/>
</NO_OF_ITEMS>
<TOTAL>
<xsl:value-of select="$fields[position()=4]"/>
</TOTAL>
<LOCATION>
<xsl:value-of select="$fields[position()=5]"/>
</LOCATION>
<EMP_NO>
<xsl:value-of select="EMP_NO"/>
</EMP_NO>
<USE_BY_DATE>
<xsl:value-of select="USE_BY_DATE"/>
</USE_BY_DATE>
<DEPOT>
<xsl:value-of select="DEPOT"/>
</DEPOT>
</ORDER>
</xsl:template>
<!-- this template copies everything that doesn't match another template -->
<xsl:template match="#* | node()">
<xsl:copy>
<xsl:apply-templates select="#* | node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>

I want substring key use on condition base

I have two param one is for separator and second is for sub
string if p then substring-before otherwise substring-after.
my Input XML .
<?xml version="1.0" encoding="iso-8859-1"?>
<results>
<result>
<Store>0180|1</Store>
</result>
<result>
<Store>0180|2</Store>
</result>
<result>
<Store>0181</Store>
</result>
<result>
<Store>0183</Store>
</result>
<result>
<Store>abc</Store>
</result>
<result>
<Store>def</Store>
</result>
<result>
<Store>0181|2</Store>
</result>
<result>
<Store>0180|3</Store>
</result>
<result>
<Store>0181|1</Store>
</result>
</results>
Xslt if fix=p then substring-before otherwise substring-after on key :
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:output method="xml" indent="yes"/>
<xsl:param name="name" select="'|'"/>
<xsl:param name="fix" select="'p'"/>
<xsl:choose>
<xsl:when fix='p'>
<xsl:key name="groups" match="/results/result" use="substring-before(Store,'|')" />
</xsl:when>
<otherwise>
<xsl:key name="groups" match="/results/result" use="substring-after(Store,'|')" />
</otherwise>
</xsl:choose>
<
<xsl:template match="/results">
<xsl:choose>
<xsl:when test="$fix='p'">
<xsl:apply-templates select="result[generate-id() = generate-id(key('groups', substring-before(Store,'|'))[1])]"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="result[generate-id() = generate-id(key('groups', substring-after(Store,'|'))[1])]"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="result">
<xsl:choose>
<xsl:when test="$fix='p'">
<xsl:for-each select="key('groups', substring-before(Store,'|'))">
<xsl:choose>
<xsl:when test="contains(Store,'|')">
<td>
<xsl:value-of select="substring-before(Store,'|')"/>
<xsl:value-of select="'|'"/>
<xsl:value-of select="position()"/>
</td>
</xsl:when>
<xsl:otherwise>
<td>
<xsl:value-of select="Store"/>
</td>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:when>
<xsl:otherwise>
<xsl:for-each select="key('groups', substring-before(Store,'|'))">
<xsl:choose>
<xsl:when test="contains(Store,'|')">
<td>
<xsl:value-of select="substring-after(Store,'|')"/>
<xsl:value-of select="'|'"/>
<xsl:value-of select="position()"/>
</td>
</xsl:when>
<xsl:otherwise>
<td>
<xsl:value-of select="Store"/>
</td>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
An xsl:key definition must be at the top level of your stylesheet.
Conversely, xsl:choose cannot be at the top level.
Try this as your starting point;
XSLT 1.0
<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="*"/>
<xsl:param name="key-direction" select="'before'"/>
<xsl:key name="key-before" match="result" use="substring-before(Store, '|')"/>
<xsl:key name="key-after" match="result" use="substring-after(Store, '|')"/>
<xsl:template match="/results">
<xsl:copy>
<xsl:choose>
<xsl:when test="$key-direction='before'">
<xsl:apply-templates select="result[generate-id()=generate-id(key('key-before', substring-before(Store,'|'))[1])]"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="result[generate-id() = generate-id(key('key-after', substring-after(Store,'|'))[1])]"/>
</xsl:otherwise>
</xsl:choose>
</xsl:copy>
</xsl:template>
<!-- more templates -->
</xsl:stylesheet>
Note also that:
substring-before('abc', '|')
returns an empty string. This means that:
<Store>0181</Store>
and
<Store>0181|1</Store>
are not going to be grouped together, unless you replace:
substring-before(Store, '|')
with:
substring-before(concat(Store, '|'), '|')

How to pass dynamic separator in key XSLT1.0

How to pass dynamic separator in , here i passed '|' as static , when i declare variable in xsl and used this place it gives error.
<xsl:variable name="separator" select="'|'"/>
<xsl:key name="key-before" match="result" use="substring-before(Store, $separator)"/>
input XML
<?xml version="1.0" encoding="iso-8859-1"?>
<results>
<result>
<Store>0180|1</Store>
</result>
<result>
<Store>0180|2</Store>
</result>
<result>
<Store>0181</Store>
</result>
<result>
<Store>0183</Store>
</result>
<result>
<Store>abc</Store>
</result>
<result>
<Store>def</Store>
</result>
<result>
<Store>0181|2</Store>
</result>
<result>
<Store>0180|3</Store>
</result>
<result>
<Store>0181|1</Store>
</result>
</results>
XSLT:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:output method="xml" indent="yes"/>
<xsl:param name="key-direction" select="'p'"/>
<xsl:param name="separator" select="results/sep"/>
<xsl:variable name="demo" select="substring-before(Store,$separator)"/>
<xsl:key name="group-before" match="/results/result" use="substring-before(Store,$demo)" />
<xsl:key name="group-after" match="/results/result" use="substring-before(Store,$demo)" />
<xsl:template match="/results">
<xsl:choose>
<xsl:when test="$key-direction='p'">
<xsl:apply-templates select="result[generate-id() = generate-id(key('group-before', substring-before(Store,$separator))[1])]"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="result[generate-id() = generate-id(key('group-after', substring-before(Store,$separator))[1])]"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="result">
<xsl:choose>
<xsl:when test="$key-direction='p'">
<xsl:for-each select="key('group-before', substring-before(Store,$separator))">
<xsl:choose>
<xsl:when test="contains(Store,'|')">
<td>
<xsl:value-of select="substring-before(Store,$separator)"/>
<xsl:value-of select="'|'"/>
<xsl:value-of select="position()"/>
</td>
</xsl:when>
<xsl:otherwise>
<td><xsl:value-of select="Store"/></td>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:when>
<xsl:otherwise>
<xsl:for-each select="key('group-after', substring-after(Store,$separator))">
<xsl:choose>
<xsl:when test="contains(Store,'|')">
<td>
<xsl:value-of select="substring-after(Store,$separator)"/>
<xsl:value-of select="'|'"/>
<xsl:value-of select="position()"/>
</td>
</xsl:when>
<xsl:otherwise>
<td><xsl:value-of select="Store"/></td>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
What you ask for is not possible (in XSLT 1.0). Neither the match nor the use attribute of xsl:key can contain a reference to a variable.

Reading values of XML tag in variables inside XSLT

I could not find a similar question anywhere, so thats why posting this new question.
I have an XML that I want to read and convert into SQL using XSLT. The trick part is that the XML elements(i.e. the names) are not known and the XSD for the XML is generated on the fly.
But what is known is certain attributes of the elements.
The XML looks like this :
<?xml version="1.0" encoding="UTF-8"?>
<et:ItemRecordList xmlns:et="urn:org:easetech:easytest:schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:org:easetech:easytest:schema ItemRecord.xsd ">
<ItemRecord recordId="idvalue0" tableName="item_record">
<itemId columnName="item_id" idColumn="true" length="36" nullable="false">itemId</itemId>
<databaseInstitution columnName="database_institution" length="255" nullable="false">0</databaseInstitution>
<lastModifiedDate columnName="last_modified_date" length="255" nullable="false">2001-12-31T12:00:00</lastModifiedDate>
</ItemRecord>
</et:ItemRecordList>
I want to use this XML and convert it into an INSERT SQL statement using XXSLT.
I created an XSLT like this :
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8" />
<xsl:template match="/">
<xsl:for-each select="/*/*">
INSERT INTO
<xsl:value-of select="#tableName" />
(
<xsl:for-each select="/*/*/*">
<xsl:variable name="columnName"><xsl:value-of select="#columnName"/></xsl:variable>
<xsl:choose>
<xsl:when test="#columnName">
<xsl:value-of select="$columnName"/>
<xsl:if test="position()!=last()">
<xsl:text>, </xsl:text>
</xsl:if>
</xsl:when>
</xsl:choose>
</xsl:for-each>
)
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
which gives me the output like this :
INSERT INTO item_record (item_id, database_institution, last_modified_date)
But I don't know how to create the value part of the query. The value is the value we get using
<xsl:value-of select="." />
I tried concatenating the values, but unfortunately concat didnt work for me. I also played around with xsl:variable but couldnt make it work. If someone could help me with the XSLT that I can use to create to output like below that would be really appreciated.
INSERT INTO item_record (item_id, database_institution, last_modified_date) values (itemId,0,2001-12-31T12:00:00)
How about:
<xsl:template match="/">
<xsl:for-each select="/*/*">
<xsl:text>INSERT INTO </xsl:text>
<xsl:value-of select="#tableName" />
<xsl:text> (</xsl:text>
<xsl:for-each select="*[#columnName]">
<xsl:value-of select="#columnName"/>
<xsl:if test="position()!=last()">
<xsl:text>, </xsl:text>
</xsl:if>
</xsl:for-each>
<xsl:text>) values (</xsl:text>
<xsl:for-each select="*[#columnName]">
<xsl:value-of select="."/>
<xsl:if test="position()!=last()">
<xsl:text>, </xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
The next XSLT will generate the query as wanted
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" />
<xsl:variable name="newline" select="'
'" />
<xsl:template match="/">
<xsl:apply-templates select="*/*/#tableName" />
</xsl:template>
<xsl:template match="#tableName">
<xsl:value-of select="concat('INSERT INTO ', ., ' (')" />
<xsl:apply-templates select="parent::*/*/#columnName" />
<xsl:value-of select="') VALUES ('" />
<xsl:apply-templates select="parent::*/*" mode="values" />
<xsl:value-of select="concat(')', $newline)" />
</xsl:template>
<xsl:template match="#columnName">
<xsl:choose>
<xsl:when test="position() = last()">
<xsl:value-of select="." />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat(., ', ')" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="*" mode="values">
<xsl:choose>
<xsl:when test="position() = last()">
<xsl:value-of select="." />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat(., ', ')" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>

XSL match multiple variables with XML

I'm trying to match xsl variables i.e. key1, key2 with xml node strings.
Problem: the xsl variables can vary like key1, key2, key3, key4, until key.length...
Question: How can I modify my xsl so when the key[i] is used, then ti will display all the xml node matches.
Here's my XML:
<?xml version="1.0" encoding="UTF-8"?>
<document>
<metadata>
<field>marketing business</field>
<field>PageTitle1 One</field>
<field>marketing business link</field>
<field>planning development</field>
<field>PageTitle2 Two</field>
<field>planning development link</field>
<field>learning development</field>
<field>PageTitle3 Threee</field>
<field>learning development link</field>
</metadata>
</document>
Here's my XSL:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- Edited by XMLSpy® -->
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:variable name="key1">marketing</xsl:variable>
<xsl:variable name="key2">business</xsl:variable>
<xsl:for-each select="document/metadata/field">
<xsl:choose>
<xsl:when test="contains(.,$key1) and contains(.,$key2)">
match <xsl:value-of select="." /><br/>
</xsl:when>
<xsl:when test="contains(.,$key2)">
match <xsl:value-of select="." /><br/>
</xsl:when>
<!--... add other options here-->
<xsl:otherwise></xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:template>
Result:
match marketing business
match marketing business link
Any help? or is there a way to put this in an array-like variable or any different approach?...
Consider putting your "keys" in a separate XML document, call it "keys.xml"
<keys>
<key>marketing</key>
<key>business</key>
</keys>
Then, you can create a single variable in your XSLT to reference this document
<xsl:variable name="keys" select="document('keys.xml')/keys" />
With this variable you can then, for example, check if your field element matches all the keys like so:
<xsl:variable name="matches" select="count($keys/key[contains(current(), .)])" />
<xsl:choose>
<xsl:when test="$matches = count($keys/key)">
Try this XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/>
<xsl:variable name="keys" select="document('keys.xml')/keys" />
<xsl:variable name="totalkeys" select="count($keys/key)" />
<xsl:template match="/">
<xsl:for-each select="document/metadata/field">
<xsl:variable name="matches" select="count($keys/key[contains(current(), .)])" />
<xsl:choose>
<xsl:when test="$matches = $totalkeys">
matches all <xsl:value-of select="." /><br/>
</xsl:when>
<xsl:when test="$matches = 1">
matches one <xsl:value-of select="." /><br/>
</xsl:when>
<xsl:when test="$matches > 0">
matches some <xsl:value-of select="." /><br/>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>