Time format in XSLT 2.0 - function

I worked with xslt 2.0 and Java( Saxon-HE ).Saxon-HE do not support xslt date-time format.I have current-date() and current-time() functions and I need them in the following format time(17:31), date(03/06).Please help me and give any suggestion hot to do it.Thanks a lot of

Please try the below tranformation:
<?xml version='1.0'?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output method="text"/>
<xsl:template match="test">
<xsl:variable name="currenttime" select="current-dateTime()" as="xs:dateTime"/>
<xsl:value-of select="format-dateTime($currenttime,'[H]')"/><xsl:text>:</xsl:text><xsl:value-of select="format-dateTime($currenttime,'[m]')"/>
<xsl:text>
</xsl:text>
<xsl:value-of select="format-dateTime($currenttime,'[M]')"/><xsl:text>/</xsl:text><xsl:value-of select="format-dateTime($currenttime,'[D]')"/>
</xsl:template>
</xsl:stylesheet>

Related

Reference to undeclared namespace prefix: 'json'. while renaming xml attibute with xslt

Updated with Minimal, Complete and Verifiable information thanks #Kenneth for drawing my attention.
So, I'm trying to rename an xml attribute using xslt, but I keep getting this error message:
Reference to undeclared namespace prefix: 'json'.
This is my source xml:
<?xml version="1.0" encoding="utf-8"?>
<data>
<code>SO000009</code>
<businessPartner>70833A356B9A428CBDDCD2A76A49681F</businessPartner>
<startDateTime>2018-01-25T15:24:27Z</startDateTime>
<subject>Test</subject>
<equipments jsonArray="true">80202</equipments>
</data>
This is how I want the xml to be:
<?xml version="1.0" encoding="utf-16"?>
<data xmlns:json="http://james.newtonking.com/projects/json">
<code>SO000009</code>
<businessPartner>70833A356B9A428CBDDCD2A76A49681F</businessPartner>
<startDateTime>2018-01-25T15:24:27Z</startDateTime>
<subject>Test</subject>
<equipments json:Array="true">80202</equipments>
</data>
And this is my xslt:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:template match="/data">
<data xmlns:json="http://james.newtonking.com/projects/json">
<xsl:apply-templates select="node()|#*" />
</data>
</xsl:template>
<xsl:template match="#*">
<xsl:attribute name="{local-name()}">
<xsl:value-of select="." />
</xsl:attribute>
</xsl:template>
<xsl:template match="node()">
<xsl:copy>
<xsl:apply-templates select="node()|#*" />
</xsl:copy>
</xsl:template>
<xsl:template match="#jsonArray">
<xsl:attribute name="json:Array">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
When I'm trying to convert my xml, I keep getting this message:
Error occurred while compiling stylesheet 'CS_jsonArray.xslt'.
Code: 0x80004005
Reference to undeclared namespace prefix: 'json'.
After looking in the 'Related' sidebar, I did found the answer to my own question.
XSL transformation - Namespace prefix undeclared
So for those who have a same issue, be sure the namespace you want to change the attribute names for, is also in the xslt tag itself...
This is how my xslt started:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>...
This is how I changed it:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:json="http://james.newtonking.com/projects/json">
<xsl:output indent="yes"/>...

Convert Embedded JSON to XML using XSLT

When transforming an XML document with XSLT, is it possible to convert embedded JSON (i.e. JSON formatted content) in the process?
For example the following: -
<form>
<data>[{"id":1,"name":"Hello"},{"id":2,"name":"World"}]</data>
</form>
Would be converted to: -
<form>
<data>
<id name="Hello">1</id>
<id name="World">2</id>
</data>
</form>
Parsing JSON is supported in XSLT 3.0 so using the commercial versions of Saxon 9.7 you could use
<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:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="data">
<xsl:copy>
<xsl:apply-templates select="parse-json(.)?*"/>
</xsl:copy>
</xsl:template>
<xsl:template match=".[. instance of map(xs:string, item())]">
<id name="{.?name}">
<xsl:value-of select=".?id"/>
</id>
</xsl:template>
</xsl:stylesheet>
Using the open source version of Saxon 9.7 (i.e. Saxon 9.7 HE) the following takes up the suggestion made by wero to use json-to-xml and shows how to implement the requirement:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:fn="http://www.w3.org/2005/xpath-functions"
xmlns:math="http://www.w3.org/2005/xpath-functions/math"
exclude-result-prefixes="xs math fn"
version="3.0">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="#* | node()">
<xsl:copy>
<xsl:apply-templates select="#* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="data">
<xsl:copy>
<xsl:apply-templates select="json-to-xml(.)//fn:map"/>
</xsl:copy>
</xsl:template>
<xsl:template match="fn:map">
<id name="{fn:string[#key = 'name']}">
<xsl:value-of select="fn:number[#key = 'id']"/>
</id>
</xsl:template>
</xsl:stylesheet>
Saxon 9.7 HE is available on Maven and from http://saxon.sourceforge.net/
It should be possible in XSLT 3.0, given that it has a json-to-xml function:
Parses a string supplied in the form of a JSON text, returning the
results in the form of an XML document node.
You could try to get this to run with the current implementation in Saxon.

Retrieve XML Variable in XSL file and say YES if found

I have problems with the Xpath expression test="$roles/roles/role='HOBSCS1GB'" . Can anyone help in solving. Thanks
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:template match="/">
<xsl:variable name="roles">
<roles>
<role>HOBSCS1ROI</role>
<role>HOBSCS1GB</role>
<role>HOBSCS1FT</role>
</roles>
</xsl:variable>
<xsl:if test="$roles/roles/role='HOBSCS1GB'">
<xsl:value-of select="'YES'"/>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
Assuming you want to find if a the roles element has one or more role elements with text = 'HOBSCS1GB': (Works in Saxon)
<xsl:if test="$roles/roles[role='HOBSCS1GB']">
<xsl:value-of select="'YES'"/>
</xsl:if>
Note that certain parsers like Microsoft may require you to tell the parser that $roles is a result tree fragment, by using node-set(), like so: (Works in msxsl)
<xsl:stylesheet ... xmlns:msxsl="urn:schemas-microsoft-com:xslt" ... />
<xsl:if test="msxsl:node-set($roles)/roles[role='HOBSCS1GB']">
<xsl:value-of select="'YES'"/>
</xsl:if>
Or in xsltproc:
<xsl:stylesheet ... xmlns:exsl="http://exslt.org/common" ... />
<xsl:if test="exsl:node-set($roles)/roles[role='HOBSCS1GB']">
<xsl:value-of select="'YES'"/>
</xsl:if>

xml tags passed as arguments to xsl

How to modify the below xsl to process parameters whose value is tags. Instead of using w:p and w:pPr/w:pStyle/#w:val i will be passing them as args
Actual XSl:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ve="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml"
>
<xsl:param name="styleName"/>
<xsl:output method="text"/>
<xsl:template match="w:p"/>
<xsl:template match="w:p[w:pPr/w:pStyle/#w:val[matches(., concat('^(',$styleName,')$'),'i')]]">
<xsl:value-of select="."/><xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>
Required XSL:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ve="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml">
<xsl:param name="styleName" select="'articletitle'"/>
<xsl:param name="para" select="'//w:p[w:pPr/w:pStyle/#w:val[matches(.,concat('^(',$styleName,')$')]]'"/>
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:for-each select="$para">
<xsl:value-of select="."/><xsl:text>
</xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
NOTE: You should get used to give information about which version of xslt and which processor you are using. In this case, the answer is valid only if you are using XSLT 2.0
This is not a complete answer, but you can start by looking at this approach:
Try using local-name and in-scope-prefixes (only available in XSLT 2.0) to match a node dynamically.
Here you have an example template to replace your empty template:
<xsl:template match="*[local-name()=substring-after($para,':') and in-scope-prefixes(.)[.=substring-before($para,':')]]"/>
For the second part of the expression ($parastyle), I can only think about writing your own function to evaluate it dynamically.
I'll try to post an example of such a function later on.
I fugured out the problem in my coding, is in second line,
<xsl:param name="para" select="'//w:p[w:pPr/w:pStyle/#w:val[matches(.,concat('^(',$styleName,')$')]]'"/>
Since i have given the quotes in select attribute the value has been considered as string instead of xpath expression.

how to interpret HTML in XSL

I have the following xml
<results>
<first-name>Carl<first-name>
<data><b> This is carl's data </b></data>
</results>
How do I include the bold tags which is present in the <data> tag to be a part of the output but rendered as an HTML
When I say <xsl:value-of select="results/data"/> The output is
<b> This is carl's data </b>
I want to achieve "This is carl's data" as the output in bold.
Well <xsl:copy-of select="results/data/node()"/> is a start but if the requirement is part of a larger problem then you are better off writing a template for data elements which uses apply-templates to push the child nodes through some template(s) for copying HTML elements through to the output.
I am sure someone will let me know if I am being naive:
<?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="html" indent="yes"/>
<xsl:template match="/results">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="first-name">
<xsl:value-of select="." />
<xsl:text>: </xsl:text>
</xsl:template>
<xsl:template match="data">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="b">
<b>
<xsl:value-of select="." />
</b>
</xsl:template>
</xsl:stylesheet>