i have troubles filtering with XSLT, basically i have an xml, where i would like to get only those items where the Due Date falls into interval of 3 months ... i've written the following:
<xsl:variable name="TaskRows" select="/dsQueryResponse/Tasks/Rows/Row[#DueDate > $IsoBeginQuartDate AND #DueDate < $IsoEndQuartDate]"/>
But I get an error: "Failed seting processor stylesheet: expected token ']' found 'NAME' ...
IsoDates are calculated and formated dates in ISO format ...
Any idea, how to do it, or i can't use "AND" when filtering?
PS: i'm using XSLT 1.0
There is case-sensitivity at work here! Try using 'and' instead of 'AND'.
Unfortunately in XSLT 1.0, you can't compare dates to see if a date is between two values.
What you could do is something like this:
<!-- Make sure to format this variables as YYYYMMDD -->
<xsl:variable name="$IsoBeginQuartDate">20130101</xsl:variable>
<xsl:variable name="$IsoBeginQuartDate">20131231</xsl:variable>
<!-- Make sure #DueDate also has the format YYYYMMDD, in this example I assume the DueDate has format YYYY-MM-DD -->
<xsl:variable name="TaskRows" select="/dsQueryResponse/Tasks/Rows/Row[translate(#DueDate, '-', '') > $IsoBeginQuartDate and translate(#DueDate, '-', '') < $IsoEndQuartDate]"/>
You now get errors, because > and < or not supported for strings or dates.
Related
I have multiple fields with the same name "item" inside json object, how can I combine their values under one field (as an array) using regex
sample input:
{"item":"A","item":"B","item":"C"}
expected output:
"item": ["A","B","C"]
note that we could have more than 3 items on above sample
I have tried {"item":"(.*?)","item":"(.*?)","item":"(.*?)"} but here I'm limited with 3 items, I need something to work for any number of items.
Thanks
The conversion you want can be performed quite easily in XSLT 2.0 or higher using:
<xsl:text>"item": [</xsl:text>
<xsl:value-of select="for $i in tokenize(translate($input, '{}', ''), ',') return substring-after($i, ':')" separator=","/>
<xsl:text>]</xsl:text>
Demo: https://xsltfiddle.liberty-development.net/eiorv1e
Of course, if your ultimate goal is to parse the input in order to use its values, then it's not necessary to put it back as JSON.
I want to compare two dates in XSLT (1.0). Here I have mentioned hard coded dates
<xsl:variable name="DATE1" select="ms:format-date(16-FEB-19, 'dd-MMM-yy')" />
<xsl:variable name="DATE2" select="ms:format-date(01-MAY-19, 'dd-MMM-yy')" />
<xsl:if test="$DATE1 $lt; $DATE2">
</xsl:if>
I tried above but not getting proper result.
It looks like you're using some kind of extension function ms:format-date to format the dates. If you can format them as pure numeric YYYYMMDD then you can compare them as numbers. XSLT 1.0 does not offer a "<" operator for strings, let alone for dates.
Do think about moving forward to a later XSLT version (available from third parties) rather than asking the StackOverflow community to help you use a 20-year old version of the language.
I have an array of element where a:value element can have different values in it. In case the element contains date in Zulu format i.e.: 2019-04-17T10:42:48.0135859, I need to change it to YYYY-MM-DD format. I have already come up with a solution. However, I am more interested in the matching i:type="b:dateTime" in my condition. Which means if i:type is equal to or contains b:dateTime then the XSLT will fetch the date and do the required transformation.
The input XML is:
<Properties
xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"
>
<a:KeyValueOfstringanyType>
<a:Key>dtDynamicModifyDate</a:Key>
<a:Value i:type="b:dateTime"
xmlns:b="http://www.w3.org/2001/XMLSchema"
>2019-04-17T10:42:48.0135859</a:Value>
</a:KeyValueOfstringanyType>
<a:KeyValueOfstringanyType>
<a:Key>tiEnrollmentStatus</a:Key>
<a:Value i:type="b:string"
xmlns:b="http://www.w3.org/2001/XMLSchema"
>Enrolled</a:Value>
</a:KeyValueOfstringanyType>
<a:KeyValueOfstringanyType>
<a:Key>tiNumberOfEnrollments</a:Key>
<a:Value i:type="b:int"
xmlns:b="http://www.w3.org/2001/XMLSchema"
>1</a:Value>
</a:KeyValueOfstringanyType>
<a:KeyValueOfstringanyType>
<a:Key>dtModifyDate</a:Key>
<a:Value i:type="b:dateTime"
xmlns:b="http://www.w3.org/2001/XMLSchema"
>2019-04-16T15:57:39.331-04:00</a:Value>
</a:KeyValueOfstringanyType>
</Properties>
The transformation is available here: https://xsltfiddle.liberty-development.net/ncdD7mC/1
Instead of this condition, I want the above condition to be checked (i:type is equal to or contains b:dateTime)
<xsl:when test="contains($payload/*[local-name()='Value'], '-') and contains($payload/*[local-name()='Value'], 'T') and contains($payload/*[local-name()='Value'], ':')">
Any pointer for the XPATH will be appreciated.
Cheers,
Sierra
The expression I think you are looking for is this...
<xsl:when test="$payload/*[local-name()='Value']/#*[name()='i:type'] ='b:dateTime'">
However, this would fail if the namespace prefix changed, so perhaps you should do this:
<xsl:when test="$payload/*[local-name()='Value']/#*[local-name()='type'] ='b:dateTime'">
But this could potentially not give you the right results if you had two attributes named type in different namespace. The only real solution is to declare the xmlns:i namespace in the XSLT, then you would do this:
<xsl:when test="$payload/*[local-name()='Value']/#i:type ='b:dateTime'">
How do I compare the year of a given date to int?
<if test="year(#varDate)>=1900">
true
</if>
Where the format of the date in the input file is:
<date varDate="31/12/1999" />
If you are stuck with XSLT 1.0, the most common way is to extract the year-part, like so:
substring-before('1994-12-31', '-')
Or, if your format is, let's say dd/MM/yyyy, you can do1:
substring-after('31/12/1999', '/')
In your case that would be something along those lines:
<xsl:if test="substring-after('31/12/1999', '/') > 1900">
true
</xsl:if>
Since you didn't provide input data, I assume you can work out the details yourself. Your original question was tagged xslt-1.0, but this has since changed. If that means that you can use XSLT 2.0 or higher, and you have an actual typed xs:date value, you can also use fn:year-from-date:
<xsl:if test="year-from-date(xs:date('1994-12-31')) > 1900">
true
</xsl:if>
1 This is not enough as there are two slashes, use substring-after(substring-after('31/12/1999', '/'), '/'), as seen in Michael's post (credit to him).
it turns out my date is in a different format that in solution above
(dd/mm/yyyy).
If that's really your date format - i.e.both days and month are always padded to two digits - you can use:
<if test="substring(#varDate, 7) >= 1900">
as your test.
If not, you'll need:
<if test="substring-after(substring-after(#varDate, '/'), '/') >= 1900">
I have a xslt code for getting the date from the database.the code is working correctly and I got the output ,but the problem is the date is not in correct format.here is the result.
output: 2013-05-07T11:27:46.7+02:00
my code is
<xsl:variable name="lastchange" select="shop:ExecStoredProcedure('kt_Lastchange',concat('#account:',$accid,',#itemnumber:',id))"></xsl:variable>
<textarea>
<xsl:value-of select ="$lastchange"/>
</textarea>
anyone can help for getting the correctly format of date?
If you are using
XSLT 1.0 version, use EXSLT - date:format-date date extension
XSLT 2.0 version, use built-in: Formatting Dates and Times date extension
Code
<xsl:variable name="dt" as="xs:dateTime" select="xs:dateTime('2012-10-21T22:10:15')"/>
<xsl:value-of select="format-dateTime($dt, '[Y0001]/[M01]/[D01]')"/>