meow00
asked on
more questions on Converting 4e-3 to 0.004
Hi experts,
I have the following xml file:
<?xml version="1.0" encoding="UTF-8"?>
<MyFile>
<MySchema>
<MyField import="3.399e-001" name="name1" type="good"/>
<MyField import="4.690e-001" name="name2" type="good"/>
<MyField import="5.746e-001" name="name3" type="good"/>
<MyField import="2.298e-001" name="name4" type="good"/>
<MyField name="subject" type="bad"/>
</MySchema>
</MyFile>
-------------------------- ---------- ----------
and I want the output to be
<?xml version="1.0" encoding="UTF-8"?>
<MyFile>
<MySchema>
<MyField import="0.003399" name="name1" type="good"/>
<MyField import="0.004690" name="name2" type="good"/>
<MyField import="0.005746" name="name3" type="good"/>
<MyField import="0.002298" name="name4" type="good"/>
<MyField name="subject" type="bad"/>
</MySchema>
</MyFile>
-------------------------- ---------- ------
The following is my code, but it didn't work. Could anyone please help me? Thanks.
I have the following xml file:
<?xml version="1.0" encoding="UTF-8"?>
<MyFile>
<MySchema>
<MyField import="3.399e-001" name="name1" type="good"/>
<MyField import="4.690e-001" name="name2" type="good"/>
<MyField import="5.746e-001" name="name3" type="good"/>
<MyField import="2.298e-001" name="name4" type="good"/>
<MyField name="subject" type="bad"/>
</MySchema>
</MyFile>
--------------------------
and I want the output to be
<?xml version="1.0" encoding="UTF-8"?>
<MyFile>
<MySchema>
<MyField import="0.003399" name="name1" type="good"/>
<MyField import="0.004690" name="name2" type="good"/>
<MyField import="0.005746" name="name3" type="good"/>
<MyField import="0.002298" name="name4" type="good"/>
<MyField name="subject" type="bad"/>
</MySchema>
</MyFile>
--------------------------
The following is my code, but it didn't work. Could anyone please help me? Thanks.
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:template match="MySchema">
<xsl:element name="MyField">
<xsl:attribute name="import">
<xsl:value-of select="format-number(., '#.####')"/>
</xsl:attribute>
</xsl:element>
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="*">
<xsl:element name="{local-name()}">
<!-- go process attributes and children -->
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="@*">
<xsl:attribute name="{local-name()}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
ASKER
I added a bit more changes ... now the output is:
<?xml version="1.0" encoding="UTF-8"?><MyFile>
<MySchema>
<MyField name="name1" type="good" import="NaN"/>
<MyField name="name2" type="good" import="NaN"/>
<MyField name="name3" type="good" import="NaN"/>
<MyField name="name4" type="good" import="NaN"/>
<MyField name="subject" type="bad" import="NaN"/>
</MySchema>
</MyFile>
-------------------------- ---------- ---------- ------
Does anyone know why? Thanks!
<?xml version="1.0" encoding="UTF-8"?><MyFile>
<MySchema>
<MyField name="name1" type="good" import="NaN"/>
<MyField name="name2" type="good" import="NaN"/>
<MyField name="name3" type="good" import="NaN"/>
<MyField name="name4" type="good" import="NaN"/>
<MyField name="subject" type="bad" import="NaN"/>
</MySchema>
</MyFile>
--------------------------
Does anyone know why? Thanks!
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:template match="MyField">
<xsl:copy>
<xsl:attribute name="name"><xsl:value-of select="@name" />
</xsl:attribute>
<xsl:attribute name="type"><xsl:value-of select="@type" />
</xsl:attribute>
<xsl:attribute name="import">
<xsl:value-of select="number(@import)" />
</xsl:attribute>
</xsl:copy>
</xsl:template>
<xsl:template match="*">
<xsl:element name="{local-name()}">
<!-- go process attributes and children -->
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="@*">
<xsl:attribute name="{local-name()}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
Actually, I don't know how to handle numbers with an exponent.
If you use a MSXML processor, you can try to use a script as follows:
If you use a MSXML processor, you can try to use a script as follows:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:user="http://mycompany.com/mynamespace" version="2.0">
<msxsl:script language="JScript" implements-prefix="user">
function convert( n ) {
return parseFloat( n.item(0).text );
}
</msxsl:script>
<xsl:template match="MyField">
<xsl:element name="MyField">
<xsl:apply-templates select="@* | *"/>
</xsl:element>
</xsl:template>
<xsl:template match="@import">
<xsl:attribute name="import"><xsl:value-of select="format-number(user:convert(.), '#0.####' )"/></xsl:attribute>
</xsl:template>
<xsl:template match="*">
<xsl:element name="{local-name()}">
<!-- go process attributes and children -->
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="@*">
<xsl:attribute name="{local-name()}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
please don't go using scripts as zc2 suggests, unless you realy have to.
The script forces you to use one particular processor (msxml in this case)
I see you are using XSLT2.
XPath2 has support for scientific notation as an input format for float numbers
So, your code should work. And it does with Saxon9B.
Which processor are you using for the XSLT?
Likely not an XSLT2 one. I recommend using Saxon9B then
cheers
Geert
The script forces you to use one particular processor (msxml in this case)
I see you are using XSLT2.
XPath2 has support for scientific notation as an input format for float numbers
So, your code should work. And it does with Saxon9B.
Which processor are you using for the XSLT?
Likely not an XSLT2 one. I recommend using Saxon9B then
cheers
Geert
ASKER
Hi Gertone,
I am using Xalan, and the reason I need to use Xalan is Saxon was not doing the right thing in certain cases (https://www.experts-exchange.com/questions/23405813/order-of-conditions.html).
Is there a way to resolve this issue in Xalan? ( because I can not use Saxon for the above reason)
Thanks a lot!
I am using Xalan, and the reason I need to use Xalan is Saxon was not doing the right thing in certain cases (https://www.experts-exchange.com/questions/23405813/order-of-conditions.html).
Is there a way to resolve this issue in Xalan? ( because I can not use Saxon for the above reason)
Thanks a lot!
The issue you mentioned is not a problem of saxon.
it is a problem of the old xslt transformer hidden in Java.
You could very well plug in Saxon9B and use it in Java
(the saxonica website explains how to use saxon9B in Java)
You will not have the above mentioned issue when using Saxon.
Xalan has no support for XSLT2
So you are bound to XSLT1 if you continue using Xalan.
z2c's solution will not work for you either, since that one requires msxml, not xalan.
You could develop a similar external function in Java and plug that in,
or you could simply develop a template in XSLT that does a similar thing.
Check the saxonica website www.saxonica.com and see if you could migrate to XSLT2 and saxon9B.
In the mean time I will see if I can get it working in XSLT1
it is a problem of the old xslt transformer hidden in Java.
You could very well plug in Saxon9B and use it in Java
(the saxonica website explains how to use saxon9B in Java)
You will not have the above mentioned issue when using Saxon.
Xalan has no support for XSLT2
So you are bound to XSLT1 if you continue using Xalan.
z2c's solution will not work for you either, since that one requires msxml, not xalan.
You could develop a similar external function in Java and plug that in,
or you could simply develop a template in XSLT that does a similar thing.
Check the saxonica website www.saxonica.com and see if you could migrate to XSLT2 and saxon9B.
In the mean time I will see if I can get it working in XSLT1
Here is a stylesheet that works accross multiple XSLT1 processors
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:template match="MyField">
<xsl:copy>
<xsl:attribute name="name"><xsl:value-of select="@name" />
</xsl:attribute>
<xsl:attribute name="type"><xsl:value-of select="@type" />
</xsl:attribute>
<xsl:attribute name="import">
<xsl:call-template name="SciNum2Float">
<xsl:with-param name="scinum" select="translate(@import, 'E', 'e')"/>
</xsl:call-template>
</xsl:attribute>
</xsl:copy>
</xsl:template>
<xsl:template match="*">
<xsl:element name="{local-name()}">
<!-- go process attributes and children -->
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="@*">
<xsl:attribute name="{local-name()}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
<xsl:template name="SciNum2Float">
<xsl:param name="scinum"/>
<xsl:variable name="exp" select="number(substring-a fter($scin um, 'e'))"/>
<xsl:choose>
<xsl:when test="not(string($exp) = 'NaN') and not (string(number(substring-b efore($sci num, 'e'))) = 'NaN')">
<xsl:variable name="multiplier">
<xsl:call-template name="power">
<xsl:with-param name="base" select="10"/>
<xsl:with-param name="power" select="$exp * (1 - 2 * number($exp < 0))"></xsl:with-param>
</xsl:call-template>
</xsl:variable>
<xsl:choose>
<xsl:when test="substring(substring- after($sci num, 'e'), 1, 1) = '-'">
<xsl:value-of select="number(substring-b efore($sci num, 'e')) div $multiplier "/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="number(substring-b efore($sci num, 'e')) * $multiplier"/>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>NaN</xsl:ot herwise>
</xsl:choose>
</xsl:template>
<xsl:template name="power">
<xsl:param name="base"/>
<xsl:param name="power"/>
<xsl:choose>
<xsl:when test="$power = 0">
<xsl:value-of select="1"></xsl:value-of>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="temp">
<xsl:call-template name="power">
<xsl:with-param name="base" select="$base"/>
<xsl:with-param name="power" select="$power - 1"></xsl:with-param>
</xsl:call-template>
</xsl:variable>
<xsl:value-of select="$temp * $base"></xsl:value-of>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:template match="MyField">
<xsl:copy>
<xsl:attribute name="name"><xsl:value-of select="@name" />
</xsl:attribute>
<xsl:attribute name="type"><xsl:value-of select="@type" />
</xsl:attribute>
<xsl:attribute name="import">
<xsl:call-template name="SciNum2Float">
<xsl:with-param name="scinum" select="translate(@import,
</xsl:call-template>
</xsl:attribute>
</xsl:copy>
</xsl:template>
<xsl:template match="*">
<xsl:element name="{local-name()}">
<!-- go process attributes and children -->
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="@*">
<xsl:attribute name="{local-name()}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
<xsl:template name="SciNum2Float">
<xsl:param name="scinum"/>
<xsl:variable name="exp" select="number(substring-a
<xsl:choose>
<xsl:when test="not(string($exp) = 'NaN') and not (string(number(substring-b
<xsl:variable name="multiplier">
<xsl:call-template name="power">
<xsl:with-param name="base" select="10"/>
<xsl:with-param name="power" select="$exp * (1 - 2 * number($exp < 0))"></xsl:with-param>
</xsl:call-template>
</xsl:variable>
<xsl:choose>
<xsl:when test="substring(substring-
<xsl:value-of select="number(substring-b
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="number(substring-b
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>NaN</xsl:ot
</xsl:choose>
</xsl:template>
<xsl:template name="power">
<xsl:param name="base"/>
<xsl:param name="power"/>
<xsl:choose>
<xsl:when test="$power = 0">
<xsl:value-of select="1"></xsl:value-of>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="temp">
<xsl:call-template name="power">
<xsl:with-param name="base" select="$base"/>
<xsl:with-param name="power" select="$power - 1"></xsl:with-param>
</xsl:call-template>
</xsl:variable>
<xsl:value-of select="$temp * $base"></xsl:value-of>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
ASKER
Thanks Gertone,
But I got the following error:
Description: The value of attribute "select" associated with an element type "xsl:with-param" must not contain the '<' character.
at line:
<xsl:with-param name="power" select="$exp * (1 - 2 * number($exp < 0))"></xsl:with-param>
-------------------------- ---------- --
do u know what happened? Thanks!
But I got the following error:
Description: The value of attribute "select" associated with an element type "xsl:with-param" must not contain the '<' character.
at line:
<xsl:with-param name="power" select="$exp * (1 - 2 * number($exp < 0))"></xsl:with-param>
--------------------------
do u know what happened? Thanks!
Oh, that is what the EE forum made of my code
(new functionality lead to this I am afraid)
the < in the XPath should be &lt;
I will paste my code in the code snippet pane next time
(new functionality lead to this I am afraid)
the < in the XPath should be &lt;
I will paste my code in the code snippet pane next time
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Then the output becomes:
<?xml version="1.0" encoding="UTF-8"?><MyFile>
<MySchema>
NaN
NaN
NaN
NaN
NaN
</MySchema>
</MyFile>
-------------------------
Did I miss anything? Thanks!
Open in new window