Using Saxon, increment or decrement the global variables in XSLT - xslt

I want to use a counter to increment and decrement the value in XSLT. I am able to achieve this using Apache Xalan, but now I want to achieve the same using Saxon.
My XSLT script for Xalan looks like this:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:lxslt="http://xml.apache.org/xslt"
xmlns:result="http://www.example.com/results"
extension-element-prefixes="result">
<lxslt:component prefix="result" functions="incr dcr">
<lxslt:script lang="javascript">
var count = 0;
function incr() {
count++;
return count;
}
function dcr() {
count--;
return count;
}
</lxslt:script>
</lxslt:component>
<xsl:template match="/">
a)<xsl:value-of select="result:incr()"/>
b)<xsl:value-of select="result:incr()"/>
c)<xsl:value-of select="result:dcr()"/>
</xsl:template>
</xsl:stylesheet>
Expected output is:
a)1
b)2
c)1
------------------------- my use case using saxon -------------------
This is my sample data.xml file. I want to transform this to html file.
<entity>
<record>10</record>
<record>15</record>
<record>19</record>
<record>7</record>
<record>4</record>
<record>14</record>
<record>24</record>
<entity>
I want to implement a counter for line-number and want to increment the counter and print the line-number
my expected outputs:
case 1: If record values > 14, then my output should have line-number with value as.
line-num value
1 15
2 19
3 24
case 2 : If record values < 14, then my output should have line-number with value as.
line-num value
1 10
2 7
3 4
My other use case :
<entity>
<record>10</record>
<record>15</record>
<record>19</record>
<record>7</record>
<record>20</record>
<record>14</record>
<record>24</record>
<entity>
<record>30</record>
<record>3</record>
</entity>
</entity>
<entity>
<record>5</record>
<record>17</record>
<record>19</record>
<record>6</record>
<record>70</record>
<record>9</record>
<record>35</record>
<entity>
<record>15</record>
<record>2</record>
</entity>
</entity>
This is my other use case, first <entity> record value > 15 and in second <entity> record value < 10, and my <entity> can grow bigger where i have to show only some record based on condition.
line-num value
1 19
2 20
3 24
4 30
5 5
6 6
7 2

There is no way to use Javascript in Saxon as far as I know.
If you want to use an assignable and changeable variable in Saxon 9 (EE or PE) then you can use
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:saxon="http://saxon.sf.net/"
xmlns:mf="http://example.com/mf"
extension-element-prefixes="saxon"
exclude-result-prefixes="xs saxon mf"
version="2.0">
<xsl:variable name="counter" as="xs:integer" select="0" saxon:assignable="yes"/>
<xsl:function name="mf:incr" as="xs:integer">
<saxon:assign name="counter" select="$counter + 1"/>
<xsl:sequence select="$counter"/>
</xsl:function>
<xsl:function name="mf:decr" as="xs:integer">
<saxon:assign name="counter" select="$counter - 1"/>
<xsl:sequence select="$counter"/>
</xsl:function>
<xsl:template match="/" name="main">
a)<xsl:value-of select="mf:incr()"/>
b)<xsl:value-of select="mf:incr()"/>
c)<xsl:value-of select="mf:decr()"/>
</xsl:template>
</xsl:stylesheet>
See the warnings and notes in http://saxonica.com/html/documentation/extensions/instructions/assign.html however on attempts to introduce side effects. You might want to edit your question to explain your XML input and the desired output and why you think you need such a counter variable, hopefully we can then show a pure XSLT 2.0 solution instead of using an assignable variable.
As for your requirement to process and number certain input elements, the stylesheet
<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 indent="yes"/>
<xsl:template match="entity">
<root>
<xsl:apply-templates select="record[. > 14]"/>
<xsl:apply-templates select="record[. < 14]"/>
</root>
</xsl:template>
<xsl:template match="record">
<xsl:copy>
<line-num>
<xsl:value-of select="position()"/>
</line-num>
<value>
<xsl:value-of select="."/>
</value>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
when run against the input
<entity>
<record>10</record>
<record>15</record>
<record>19</record>
<record>7</record>
<record>4</record>
<record>14</record>
<record>24</record>
</entity>
outputs
<root>
<record>
<line-num>1</line-num>
<value>15</value>
</record>
<record>
<line-num>2</line-num>
<value>19</value>
</record>
<record>
<line-num>3</line-num>
<value>24</value>
</record>
<record>
<line-num>1</line-num>
<value>10</value>
</record>
<record>
<line-num>2</line-num>
<value>7</value>
</record>
<record>
<line-num>3</line-num>
<value>4</value>
</record>
</root>
Other options are using e.g. xsl:number count="entity[. < 14]".
As for your latest requirement, I think you can still handle that using position() as long as you select the elements you want to process, e.g. the stylesheet
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0">
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:apply-templates select="/root/entity[1]//record[. > 15], /root/entity[2]//record[. < 10]"/>
</xsl:template>
<xsl:template match="record">
<xsl:value-of select="concat(position(), ' ', ., '
')"/>
</xsl:template>
</xsl:stylesheet>
when applied to the input
<root>
<entity>
<record>10</record>
<record>15</record>
<record>19</record>
<record>7</record>
<record>20</record>
<record>14</record>
<record>24</record>
<entity>
<record>30</record>
<record>3</record>
</entity>
</entity>
<entity>
<record>5</record>
<record>17</record>
<record>19</record>
<record>6</record>
<record>70</record>
<record>9</record>
<record>35</record>
<entity>
<record>15</record>
<record>2</record>
</entity>
</entity>
</root>
outputs (with an XSLT 2.0 processor like Saxon 9)
1 19
2 20
3 24
4 30
5 5
6 6
7 9
8 2

(Responding to the expanded description of the problem)
The key thing to appreciate is that this problem requires sequential processing of the record elements, in document order. This means it can't be achieved in a processor-independent way with xsl:for-each or xsl:apply-templates because these are not guaranteed to process the elements one at a time in order (recent versions of Saxon, for example, will process elements in parallel using multi-threading, and the spec allows this; this makes any attempt to update global variables ineffective).
The classic way to process elements sequentially is using head-tail recursion. Write a template or function that takes the sequence of record elements as a parameter, and the current line number as a second parameter. If the list of records is non-empty, then (a) process the first record in the list, and (b) call yourself recursively to process the rest of the list, passing the new value of the line-number.
It can be a bit mind-blowing to write code in this way the first time you try it, but it soon comes naturally.
In XSLT 3.0 there's a new construct xsl:iterate that looks more like a conventional loop: when you enter the xsl:iterate body you pass initial values for its parameters, and each time you continue to the next iteration of the loop you can set new values for the parameters.

Without javascript, using saxon extension instructions.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:saxon="http://saxon.sf.net/"
extension-element-prefixes="saxon"
exclude-result-prefixes="saxon">
<xsl:variable name="i" select="0" saxon:assignable="yes"/>
<xsl:template match="/">
a) <xsl:value-of select="$i"/>
<saxon:assign name="i" select="$i+1"/>
b) <xsl:value-of select="$i"/>
<saxon:assign name="i" select="$i+2"/>
c) <xsl:value-of select="$i"/>
<saxon:assign name="i" select="$i+3"/>
d) <xsl:value-of select="$i"/>
</xsl:template>
</xsl:stylesheet>

Related

How to not touch a record if text exist in an XML field but process the record in no text exist using XSLT 2

Using XSLT 2 how can I skip and not touch a record if a field contains text, in this case a date? I want to only process all the record that don't have a <SurveyDate> and don't touch record that already have a <SurveyDate>.
I tried using a choose statement with a test of "not(SurveyDate/text())" but this is not working. here is my complete XSL code:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
xmlns:lookup="lookup" xmlns:exsl="http://exslt.org/common" exclude-result-prefixes="lookup exsl">
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes" encoding="utf-8" media-type="xml/plain" />
<xsl:strip-space elements="*" />
<xsl:template match="node() | #*">
<xsl:copy>
<xsl:apply-templates select="node() | #*" />
</xsl:copy>
</xsl:template>
<xsl:template match="Sub">
<!-- This is the final output -->
<xsl:choose>
<xsl:when test="not(SurveyDate/text())">
<xsl:if test= "count(Request/Phase/Status) = count(Request/Phase/Status[matches(. , 'Sup|Ser|Adm|Can')])">
<Request>
<xsl:copy-of select="Request/Code"/>
<SurveyDate>
<xsl:value-of select="format-dateTime(current-dateTime(), '[Y0001]-[M01]-[D01]T[H1]:[m01]:[s01]')"/>
</SurveyDate>
</Request>
</xsl:if>
</xsl:when>
<xsl:otherwise>
<!-- just for testing remove when done -->
<Test>Do nothing</Test>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
And this is my test XML data.
<?xml version='1.0' encoding='UTF-8'?>
<document>
<businessobjects>
<Sub>
<Code>1.02</Code>
<Status>UsrWorkOrderCancelled</Status>
<Request>
<Code>1.00</Code>
<Description>Test 1</Description>
<SurveyDate>2022-11-02T22:55:55</SurveyDate>
<Phase>
<Code>1.01</Code>
<Status>UsrWorkOrderSupervisorApproved</Status>
</Phase>
<Phase>
<Code>1.02</Code>
<Status>UsrWorkOrderCancelled</Status>
</Phase>
</Request>
</Sub>
<Sub>
<Code>2.01</Code>
<Status>UsrWorkOrderSupervisorApproved</Status>
<Request>
<Code>2.00</Code>
<Description>Test 2</Description>
<SurveyDate></SurveyDate>
<Phase>
<Code>2.01</Code>
<Status>UsrWorkOrderSupervisorApproved</Status>
</Phase>
<Phase>
<Code>2.02</Code>
<Status>UsrWorkOrderCancelled</Status>
</Phase>
</Request>
</Sub>
</businessobjects>
</document>
The result XML I need is this:
<document>
<businessobjects>
<Request>
<Code>2.00</Code>
<SurveyDate>2022-11-03T21:45:13</SurveyDate>
</Request>
</businessobjects>
</document>
My advice: forget using xsl:choose or xsl:if, and instead put the conditional logic into the template's match expression:
<xsl:template match="Sub[not(Request/SurveyDate/text())]">
<!-- handle Sub without SurveyDate -->
<!-- ... -->
</xsl:template>
Leave the case where a Sub does have a SurveyDate for the identity template to handle, if you want to copy it unchanged. If you want to remove it (it's not clear from your test code what you want to do with it), you could add another template to do so:
<xsl:template match="Sub"/>
Note that template would have a lower priority than the one above, because its match expression is simpler, so it would apply only to Sub elements which did have a SurveyDate descendant.

XSLT 2 - find first missing element in source list

I have problem with XSLT and/or XPATH. Let's say I have XML Input:
<context>
<pdpid-set>
<list>
<item>1</item>
<item>2</item>
<item>4</item>
<item>6</item>
<item>7</item>
<item>8</item>
</list>
</pdpid-set>
</context>
Task is: find FIRST missing element in array pdpid-set/list. In example above answer is 3.
I tried to use <xsl:for-each to find missing element but there is no possibility to break such loop so my XSL produce more than one element in output:
<xsl:variable name="list" select="context/pdpid-set/list"/>
<xsl:variable name="length" select="count(context/pdpid-set/list/item)"/>
<xsl:for-each select="1 to ($length)">
<xsl:variable name="position" select="position()"/>
<xsl:if test="$list/item[$position] > $position">
<missing-value>
<xsl:value-of select="$position"/>
</missing-value>
</xsl:if>
</xsl:for-each>
in code above output will be:
<missing-value>3</missing-value><missing-value>4</missing-value><missing-value>5</missing-value>...
I don't want to have more than one missing-value. Any suggestion?
Even in XPath 1.0
/context
/pdpid-set
/list
/item[not(position()=.)][1]
Do note: this select the first item not aligned with the ascending order. I still think that position() is better than following-sibling axis performance wise and for code clarity. Also, it lets you easily change starting number and step like in:
/context
/pdpid-set
/list
/item[not((position() - 1) * $step + $start = .)][1]
Task is: find FIRST missing element in array pdpid-set/list. In
example above answer is 3
Here is a correct XPath 1.0 expression that when evaluates to the wanted result (3):
/*/*/*/item[not(. +1 = following-sibling::*[1])][1] + 1
The XPath expression in the currently selected answer, on the other side, selects this element:
<item>4</item>
And the complete correct XSLT 1.0 transformation is:
<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="/">
<missing-value>
<xsl:copy-of select="/*/*/*/item[not(. +1 = following-sibling::*[1])][1] + 1"/>
</missing-value>
</xsl:template>
</xsl:stylesheet>
When applied on the provided XML document, the wanted, correct result is produced:
<missing-value>3</missing-value>
Finally, if the task is to find all missing elements:
<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="xs">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match=
"item[following-sibling::* and not(number(.) +1 = following-sibling::*[1]/number())]">
<xsl:for-each select="xs:integer(.) + 1 to following-sibling::*[1]/xs:integer(.) -1">
<missing-value><xsl:copy-of select="."/></missing-value>
</xsl:for-each>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
when this XSLT 2.0 transformation is applied on the following XML document (missing 3, 5, and 6):
<context>
<pdpid-set>
<list>
<item>1</item>
<item>2</item>
<item>4</item>
<item>7</item>
<item>8</item>
</list>
</pdpid-set>
</context>
the wanted, correct result is produced:
<missing-value>3</missing-value>
<missing-value>5</missing-value>
<missing-value>6</missing-value>

Compare to current date

I have a xml file with rows like this :
<Data>
<a>something</a>
<b>20120601</b>
<c>something else</c>
</Data>
the value in is a date formatted YYYYMMDD
I have a small template that processes each row, and which is working fine (for it doesn't do much)
Now my question :
How can I process a row only if the date in B is greater (later) than 60 days before today (current date) ?
So if the date is recent -> process the row, else don't.
Here is a complete, short and simple XSLT 2.0 solution:
<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:param name="pPeriod" select="'P60D'"/>
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<xsl:template match=
"Data
[current-date()
-
xs:date(concat(substring(b,1,4),
'-',
substring(b,5,2),
'-',
substring(b,7)
)
)
gt xs:dayTimeDuration($pPeriod)
]"/>
</xsl:stylesheet>
When applied on this XML document:
<t>
<Data>
<a>something</a>
<b>20120601</b>
<c>something else</c>
</Data>
<Data>
<a>something</a>
<b>20120420</b>
<c>something else</c>
</Data>
<Data>
<a>something</a>
<b>20120301</b>
<c>something else</c>
</Data>
</t>
the wanted, correct result (last Data element "deleted") is produced:
<t>
<Data>
<a>something</a>
<b>20120601</b>
<c>something else</c>
</Data>
<Data>
<a>something</a>
<b>20120420</b>
<c>something else</c>
</Data>
</t>
As the commenter said, XSL cannot do this by itself. You would need to first work out what the date was 60 days ago, and pass this in to your XSL as a parameter.
In PHP, you could work out the day in the following way:
$date_60_days_ago = date('Y-m-d H:m:s', strtotime("-60 days"));
As for the XSL, see this XMLPlayground session (I pass the date in manually for the purpose of this demo)
http://www.xmlplayground.com/sK82Q4
As MiMo already stated there's no built in function to get the current date in xslt 1.0. You can pass params into your xslt stylesheet but this depends on the xslt processor you use.
If you pass the back date (curret date minus 60 days) as a param, your test can be as simple as that:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name="backdate" />
<xsl:template match="Data">
<xsl:if test="(./b >= $backdate)">
<xsl:apply-templates />
</xsl:if>
</xsl:template>
</xsl:stylesheet>
In xslt 2.0 you can use the built in current-date() function
<xsl:variable name="backdate" select="current-date() -60*xs:dayTimeDuration('P1D')" />
... but you'll need to cast your <b> date value to accordingly - or format the backdate variable to fit your date value.
Adopted from Dimitre's answer on subtracting days.

XSLT key() lookup

I'm trying out a sample of look-up tables in XSLT and am not able to get it to work
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" />
<xsl:key name="classification-lookup" match="classification" use="id" />
<xsl:variable name="classification-top" select="document('')/*/classifications" />
<xsl:template match="BusinessListing">
<listing>
<id>
<xsl:value-of select="id" />
</id>
<xsl:apply-templates select="$classification-top">
<xsl:with-param name="curr-label" select="." />
</xsl:apply-templates>
</listing>
</xsl:template>
<xsl:template match="classifications">
<xsl:param name="curr-label" />
<category>
<xsl:value-of select="key('classification-lookup', $curr-label/listingData/classifications/classificationId)/description" />
</category>
</xsl:template>
<classifications>
<classification>
<id>7981</id>
<description>Category1</description>
</classification>
<classification>
<id>7982</id>
<description>Category2</description>
</classification>
<classification>
<id>7983</id>
<description>Category3</description>
</classification>
<classification>
<id>7984</id>
<description>Category4</description>
</classification>
</classifications>
</xsl:stylesheet>
and the source is as below .
<?xml version="1.0"?>
<BusinessListings>
<BusinessListing>
<id>1593469</id>
<listingData>
<classifications>
<classificationId>7982</classificationId>
<classificationId>7983</classificationId>
</classifications>
</listingData>
</BusinessListing>
</BusinessListings>
In the result below , The category is empty but I need the Classification Id from the source to be matched with the id in the classification tag and the category generated .
<?xml version="1.0" encoding="UTF-8"?>
<listing>
<id>1593469</id> -- Empty I need the Category2 and Category3 here
<category/>
</listing>
I know that I may be wide off mark but I've just started off with XSLT and referred the sample here http://www.ibm.com/developerworks/xml/library/x-xsltip.html . Thanks for the help .
Your XSLT stylesheet contains an error -- according to spec, any child-element of xsl:stylesheet (aka top-level element) must be in a non-null namespace:
"*In addition, the xsl:stylesheet
element may contain any element not
from the XSLT namespace, provided that
the expanded-name of the element has a
non-null namespace URI. "
If the XSLT processor you are using doesn't raise an error, then it is non-compliant and buggy and shouldn't be used. Find and use a compliant XSLT processor (I am using .NET XslCompiledTransform, Saxon 6.5.5, ..., etc).
There are other errors, too.
Solution:
Define a new namespace with prefix (say) "x:":
Change the embedded <classifications> to <x:classifications> -- now this conforms to the Spec.
Perform more changes to the code until you get this transformation:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:x="my:x" exclude-result-prefixes="x">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:key name="classification-lookup" match="classification"
use="id" />
<xsl:template match="BusinessListing">
<listing>
<id>
<xsl:value-of select="id" />
</id>
<xsl:apply-templates/>
</listing>
</xsl:template>
<xsl:template match="classificationId">
<xsl:variable name="vCur" select="."/>
<xsl:for-each select="document('')">
<category>
<xsl:value-of select=
"key('classification-lookup',$vCur)/description" />
</category>
</xsl:for-each>
</xsl:template>
<xsl:template match="text()"/>
<x:classifications>
<classification>
<id>7981</id>
<description>Category1</description>
</classification>
<classification>
<id>7982</id>
<description>Category2</description>
</classification>
<classification>
<id>7983</id>
<description>Category3</description>
</classification>
<classification>
<id>7984</id>
<description>Category4</description>
</classification>
</x:classifications>
</xsl:stylesheet>
.4. In the above code notice the line: <xsl:for-each select="document('')"> .
The purpose of this is to make the stylesheet the current document. The key() function operates only on the current document and if you want the embedded classification elements to be indexed and used, you must change the current document (usually in this way). In XSLT 2.0 the key() function allows a 3rd argument which is a node from the document whose index should be used.
When this transformation is applied to the provided XML document:
<BusinessListings>
<BusinessListing>
<id>1593469</id>
<listingData>
<classifications>
<classificationId>7982</classificationId>
<classificationId>7983</classificationId>
</classifications>
</listingData>
</BusinessListing>
</BusinessListings>
the wanted, correct result is produced:
<listing>
<id>1593469</id>
<category>Category2</category>
<category>Category3</category>
</listing>

Highest sum of values per group in XSL

There is probably a very easy solution for this problem. I could easily do this in C#-LINQ. Unfortunately, I'm not so experienced with XPath and XSL.
I have an input XML file that contains the following structure:
<group>
<val>1</val>
<val>3</val>
<val>1</val>
</group>
<group>
<val>3</val>
<val>2</val>
<val>2</val>
</group>
Now in my XSL transform I want to define 1 variable "highestsum", which contains the highest sum of 'values'. So for the example, it would return 7, the sum of all values in the second group.
After some searching, this is the closest solution I found:
http://w3schools.invisionzone.com/index.php?showtopic=24265
But I have a feeling that there's a better way than using sorting in a template to achieve this result. Any takers?
I. A good XSLT 1.0 solution (brief, efficient and understandable):
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/*">
<xsl:for-each select="group">
<xsl:sort select="sum(val)" data-type="number"
order="descending"/>
<xsl:if test="position()=1">
<xsl:value-of select="sum(val)"/>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
when this transformation is applied on the following XML document:
<t>
<group>
<val>1</val>
<val>3</val>
<val>1</val>
</group>
<group>
<val>3</val>
<val>2</val>
<val>2</val>
</group>
</t>
the wanted, correct result is produced:
7
To get the desired variable definition, simply put the <xsl:for-each> instruvtion from the above code in the body of the variable.
II. An even better XSLT 2.0 (and actually XPath 2.0 one-liner) solution:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/*">
<xsl:sequence select="max(group/sum(val))"/>
</xsl:template>
</xsl:stylesheet>
when this transformation is applied on the same XML document, the same correct answer is produced:
7
And the wanted variable definition is simply:
<xsl:variable name="vHighestSum"
select="max(group/sum(val))"/>
Finally, the same Xpath expression can be used in XQuery to define the required variable:
let $vHighestSum := max(/*/group/sum(val))