How to display localized date? - xslt

How do i have XSLT display a localized date to the user (in the locale of the user-agent).
For example, given an xml date in ISO format (2013-09-04T10:46:19.658):
<?xml version="1.0" encoding="utf-8"?>
<Stuff>
<Created>2013-09-04T10:46:19.658</Created>
</Stuff>
And the beginnings of a stylesheet:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes" version="5.0" doctype-system="about:legacy-compat"/>
<xsl:template match="/Stuff">
<html>
<body>
Created: <xsl:value-of select="format-date('Created')"/>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
The desired output depends, of course, on the locale of the user-agent (e.g. the client's browser):
Created: 01/11/34
Created: 05.09.13
Created: 05.09.2013
Created: 05/09 2013
Created: 05/09/2013
Created: 05-09-13
Created: 05-09-2013
Created: 09.05.2013
Created: 09/05/2013
Created: 13.09.05
Created: 2013.09.05
Created: 2013.09.05.
Created: 2013/09/05
Created: 2013/9/5
Created: 2013-09-05
Created: 2013-9-5
Created: 29/10/34
Created: 5. 9. 2013
Created: 5.09.2013
Created: 5.9.2013
Created: 5.9.2013 г.
Created: 5.9.2013.
Created: 5//09//2013
Created: 5/09/2013
Created: 5/9/2013
Created: 5/9/2556
Created: 5-9-2013
Created: 9/5/2013
Does XSLT support localization?
It runs on the client
The transformation of XML into HTML happens on the client. Since the transformation happens on the client, the client (obviously) knows its own locale.
For example, the client is given some xml:
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type='text/xsl' href='/Styles/Contoso_Handheld.xslt' media='handheld'?>
<?xml-stylesheet type='text/xsl' href='/Styles/Contoso_iPhone.xslt' media='only screen and (max-device-width: 480px)'?>
<?xml-stylesheet type='text/xsl' href='/Styles/Contoso.xslt' media='all'?>
<Stuff>
<Created>2013-09-04T10:46:19.658</Created>
</Stuff>
Notice the lines where the client in instructed which XSLT to use.
<?xml-stylesheet type='text/xsl' href='/Styles/Contoso_Handheld.xslt' media='handheld'?>
<?xml-stylesheet type='text/xsl' href='/Styles/Contoso_iPhone.xslt' media='only screen and (max-device-width: 480px)'?>
<?xml-stylesheet type='text/xsl' href='/Styles/Contoso.xslt' media='all'?>
The User-Agent fetches the XSLT, transforms the XML, and displays it to the user. All this processing happens in the locale of the client.

Standard XSLT 1.0 does not have any function to localize dates.
XSLT 2.0 has date and date-time formatting functions supporting localizations: see here but the implementation can vary - for example Saxon seem not to implement the calendar / language part.
Specific XSLT implementation have extension function supporting date-time localization - see for example this.
Even if you have a formatting function supporting localization you will still have the problem of find and pass the correct locale - if the XSLT is running on the server and the result is rendered in a browser the locale of the server could be the wrong one, and so you'll need to extract the locale information from the HTTP headers or with some JavaScript and use it on the server.

Related

Please explain why I would get a no schema error when there is, in fact, an associated schema?

OK. So I am still learning the ins and outs of XSLT and associating schemas. In my company we use XSLT in a very specific way, to transform XML metadata from one schema to another. (i.e. Dublin Core to PBCore, our house standard metadata to METS, etc.) I have a plain XML file with our standard metadata tags. I transform it using an XSLT that has these declarations:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" indent="yes" encoding="UTF-8"/>
<xsl:template match="/">
<reVTMD xmlns="http://nwtssite.nwts.nara/schema/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://www.archives.gov/preservation/products/reVTMD.xsd"
recordCreation="2016-03-24T18:13:51.0Z" profile="profile1"
version="version1">
The output XML includes this:
<?xml version="1.0" encoding="UTF-8"?>
<reVTMD xmlns="http://nwtssite.nwts.nara/schema/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://www.archives.gov/preservation/products/reVTMD.xsd"
recordCreation="2016-03-24T18:13:51.0Z"
profile="profile1"
version="version1">
at the top of the document. But I still get a "There is no schema or DTD associated with the document." in Oxygen when I try to validate the document against the reVTMD schema. What am I doing wrong?
The xsi:schemaLocation attribute as its value needs a list of pairs associating a namespace with a schema location so with the input being in the namespace http://nwtssite.nwts.nara/schema/ and the schema being in the location https://www.archives.gov/preservation/products/reVTMD.xsd you need
xsi:schemaLocation="http://nwtssite.nwts.nara/schema/ https://www.archives.gov/preservation/products/reVTMD.xsd"

Read service response(json format) inside xslt 2.0

Need to read a service response inside xslt which is of format :
servicedata={"statusCode":200,"loginMessage":"Welcome User"}
its key value pair, where i can get the value of 'servicedata' but further need to get the status code value for some condition checking.
Using version 2.0 for the xslt
read few questions which suggested to use parse-json(), json-to-xml with 3.0 version of xslt, but didn't help.
Question: first using version 2.0 only can I retrieve the value for the 'statusCode' and how, if not guide me how to achieve it.
If you can move to Saxon 9.7 HE then you could use json-to-xml as follows for instance:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:math="http://www.w3.org/2005/xpath-functions/math"
exclude-result-prefixes="xs math"
version="3.0">
<xsl:template match="data">
<xsl:value-of select="json-to-xml(substring-after(., 'servicedata='))//*[#key = 'statusCode']" xpath-default-namespace="http://www.w3.org/2005/xpath-functions"/>
</xsl:template>
</xsl:stylesheet>
which for the input
<data>servicedata={"statusCode":200,"loginMessage":"Welcome User"}</data>
outputs 200.
I have not checked whether earlier versions of Saxon 9 also support that.

Parsing SOAP response using NSXMLParser with Swift

I am trying to parse the Soap response (snippet shown below) using NSXMLParser. However when I print the Element names in the didStartElemnt delegate method I only get the following elements returned.
Element's name is soap:Envelope
Element's name is soap:Body
Element's name is SearchResponse
Element's name is SearchResult
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<SearchResponse xmlns="http://www.example.com/">
<SearchResult><?xml version="1.0" encoding="utf-8"?><Results xmlns="http://www.example.com/XMLSchema/SearchResult" xmlns:gms="http://www.def.ghi.uk/CM/gms" xmlns:n2=" (more here + further elements....)
Why do I not see the Results (or any subsequent) element?
Most likely it's the second <?xml . . .> directive that appears inside the <SearchResult>. That directive is only allowed at the start of an xml file.

IBM Connections API - Adding Members to Wiki

I've been trying to add members to the wiki to no avail. Here's the link to the instructions on how to do so:
http://www-10.lotus.com/ldd/appdevwiki.nsf/xpDocViewer.xsp?lookupName=IBM+Connections+4.5+API+Documentation#action=openDocument&res_title=Updating_a_wiki_ic45&content=pdcontent
Basically, what I need to do is to retrieve the wiki first using this URL:
connectionsURL/wikis/basic/api/wiki/{wiki-label}/entry
And then append the information there and then send it back using a PUT request, Content-Type: application/atom+xml. The content passed should look like the one below based on the example:
<?xml version="1.0" encoding="UTF-8"?>
<entry xmlns="http://www.w3.org/2005/Atom">
<id>ignore</id>
<td:label xmlns:td="urn:ibm.com/td">Lake Champlain</td:label>
<category term="wiki" scheme="tag:ibm.com,2006:td/type" label="wiki">
</category>
<author>
<name>Bill Jones</name>
<snx:userid xmlns:snx="http://www.ibm.com/xmlns/prod/sn">
bf9117c0-f8f2-102c-97c4-ceb7f24c5708
</snx:userid>
<email>bjones#us.example.com</email>
</author>
<td:sharedWith xmlns:td="urn:ibm.com/td">
<ca:member
xmlns:ca="http://www.ibm.com/xmlns/prod/composite-applications/v1.0"
ca:id="new_user_id"
ca:type="user"
ca:role="editor" >
</ca:member>
<ca:member
xmlns:ca="http://www.ibm.com/xmlns/prod/composite-applications/v1.0"
ca:id="anonymous-user"
ca:type="virtual"
ca:role="reader" >
</ca:member>
</td:sharedWith>
<title type="text">Long Lake</title>
<summary type="text">
modification none
</summary>
</entry>
I tried that and I always keep getting this 400 Bad Request response:
<?xml version="1.0" encoding="UTF-8" ?>
<td:error>
<td:errorCode>InvalidRequest</td:errorCode>
<td:errorMessage>Atom entry is null</td:errorMessage>
</td:error>
Try this API - https://conServer.com/wikis/basic/api/wiki/{WIKI_LABEL}/members
Then do a PUT on that resource to change the entries (I think type should be atom/xml or atom+cat/xml
Thanks
paul

XSLT functions and namespaces

I'm kind of new to XSLT, and I've gotten basic transformation done. Next I want to try out date manipulations, since my data will have timestamps. However, I can't seem to get any date functions to work, and it greatly frustrates me. I'm testing using Firefox 3.5, xsltproc 1.1.24, xalan 1.10, and XMLSpy 2009, and they all say that the functions I'm trying to use don't exist.
My xml looks like so:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="datetime.xsl"?>
<watcher>
<event id="1" date="2009-09-04T13:49:10-0500" type="ABCD">This is a test </event>
</watcher>
</code>
My xsl looks like so:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fn="http://www.w3.org/2005/02/xpath-functions"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:template match="event[#type='ABCD']">
<!-- Date: <xsl:value-of select="day-from-dateTime(xs:dateTime(#date))"/> -->
<!-- Date: <xsl:value-of select="day-from-dateTime(#date)"/> -->
Date: <xsl:value-of select="fn:day-from-dateTime(#date)"/>
</xsl:template>
</xsl:stylesheet>
If I make the stylesheet version 2, XMLSpy complains that it can't cast my date: XSLT 2.0 Debugging Error: Error in XPath 2.0 expression (Cast failed, invalid lexical value - xs:dateTime '2009-09-04T13:49:10-0500')
If I leave it as version 1, it complains about a different error: XSLT 1.0 Debugging Error: Error in XPath expression (Unknown function - Name and number of arguments do not match any function signature in the static context - 'day-from-dateTime')
Anytime I try to change the XSL to use a namespace, such as fn:day-from-dateTime, it refuses to work at all, with all of my parsers saying that The function number 'http://www.w3.org/2005/02/xpath-functions:day-from-dateTime' is not available and variants thereof. I know from other tests that I can use the substring() function perfectly, without needing any namespace prefix, and I believe it's in the same namespace as day-from-dateTime.
I feel like it's something incredibly easy, since all of the tutorials show functions being used, but something seems to be eluding me. Could someone show me what I'm missing?
Ouch, nasty versions thing going on here. A lot of the issues you're seeing will be because the XSLT processor you're using doesn't support XPath 2.0, which is where that day-from-dateTime function comes from.
I can get what you're trying to do to work, with a Saxon processor - Saxon-B 9.1.0.6 as my processor instead of Xalan. (Xalan appears to support XPath 1.0 only, according to the documentation)
There are a few errors in your documents:
The source document should have the timezone as 05:00, not 0500
<?xml version="1.0" encoding="UTF-8"?>
<watcher>
<event id="1" date="2009-09-04T13:49:10-05:00" type="ABCD">This is a test </event>
</watcher>
The XSLT should cast the string 2009-09-04T13:49:10-05:00 into a xs:dateTime, which is what type the argument of day-from-dateTime needs to be.
Date: <xsl:value-of select="day-from-dateTime(xs:dateTime(#date))"/>
And then it works
<?xml version="1.0" encoding="UTF-8"?>
Date: 4
Hope that helps,