As a follow up to this answer, is there a way I can figure out if the data type of the XML values?
XSL transformation doc in java
eg:
<root>
<test>
true
</test>
<test1>
1
</test1>
<test2>
"abc"
</test2>
</root>
My thought:
<xsl:template match="/">
<object>
<xsl:for-each select="//*[normalize-space(.)]">
<xsl:choose>
<xsl:when test="contains(., 3)">// want to check for Integer
<Integer name="{name()}">
<xsl:value-of select="."/>
</Integer>
</xsl:when>
<xsl:otherwise>
//check for string, boolean
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</object>
</xsl:template>
I want to know how I would be able to identify in XSL the data type of 1,"abc",true as integer,string and boolean? If someone can help me understand how normalize-space(.) works it would be very helpful (:
Any help would be greatly appreciated.
You could use castable as
in XSLT 2.0 to check if the value of the element is castable as either xs:integer
or xs:boolean
(or any of the other xs datatypes).
Example...
XML Input
<root>
<test>
true
</test>
<test1>
1
</test1>
<test2>
"abc"
</test2>
</root>
XSLT 2.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 indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="test|test1|test2">
<xsl:variable name="type">
<xsl:choose>
<xsl:when test="normalize-space() castable as xs:integer">
<xsl:text>Integer</xsl:text>
</xsl:when>
<xsl:when test="normalize-space() castable as xs:boolean">
<xsl:text>Boolean</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>String</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:element name="{$type}">
<xsl:attribute name="name" select="name()"/>
<xsl:value-of select="normalize-space()"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
XML Output
<root>
<Boolean name="test">true</Boolean>
<Integer name="test1">1</Integer>
<String name="test2">"abc"</String>
</root>
If your XML is using a schema and your processor is schema aware, you could also use instance of
to check the type.
Also, you could use an if
statement instead of the xsl:choose
if you find it easier to read...
<xsl:variable name="type" select="
if (normalize-space() castable as xs:integer) then
'Integer'
else if (normalize-space() castable as xs:boolean) then
'Boolean'
else
'String'
"/>