2010-07-29 8 views
2

Pour cette XSLT:Retain nombre de chiffres au cours du traitement entrées-> number-> sortie pendant le traitement XSLT

<xsl:variable name="source0" select="number(num2)"/> 
    <xsl:variable name="source1" select="number(num3)"/> 
    s0 plain: <xsl:value-of select="$source0"/> 
    s1 plain: <xsl:value-of select="$source1"/> 
    test11: <xsl:value-of select="format-number($source0, '#.#')"/> 
    test12: <xsl:value-of select="format-number($source0, '#.###############')"/> 
    test21: <xsl:value-of select="format-number($source1, '#.#')"/> 
    test22: <xsl:value-of select="format-number($source1, '#.###############')"/> 

XML:

<num2>123456.1234</num2> 
<num3>1234567.1234</num3> 

je reçois cette sortie (en utilisant Saxon 9.2, XSLT 2.0)

s0 plain: 123456.1234 
    s1 plain: 1.2345671234E6 
    test11: 123456.1 
    test12: 123456.123399999996764 
    test21: 1234567.1 
    test22: 1234567.123399999924004 

Tout d'abord ... Je suis curieux de savoir pourquoi il change soudainement entre la notation standard et scientifique quand il eds 6 chiffres à gauche de la décimale? C'est mon problème, je veux éviter la notation scientifique. Après diverses autres questions, je découvre apparemment que je suis coincé avec la mise en format-nombre partout.

Mais le format-nombre ne semble pas fonctionner non plus. En dépit du fait que la sortie de "s1 plain" prouve que le nombre de chiffres significatifs est connu du processeur (je comprends à propos de la conversion en double et en arrière peut perdre de précision, mais il y a le bon nombre après une telle conversion, ...?), il semble qu'il n'y ait aucun moyen de produire cette valeur en notation standard non scientifique. Y a-t-il?

+0

Bonne question (+1). Voir ma réponse pour une solution qui atteint le maximum de précision. –

+0

La spécification XSLT 2.0 pour la conversion double> chaîne indique que la notation exponentielle doit être utilisée si la valeur est en dehors de la plage 1e-6 à 1e + 6. Ces points de coupure sont complètement arbitraires, bien sûr, mais vous ne voudriez pas que 1e215 soit écrit à la main ... –

+0

Il est faux de penser que "le nombre de chiffres significatifs est connu du processeur". Si vous voulez en savoir plus sur les algorithmes utilisés, la conversion de Saxon est basée sur ce fameux document: http://portal.acm.org/citation.cfm?id=93559 adapté aux exigences de la spécification XPath. –

Répondre

2

Ceci est mon problème, je veux éviter la notation scientifique . Après diverses autres questions, je découvre apparemment Je suis coincé avec mettre le numéro de format partout.

Mais le format-nombre n'apparaît pas à .

Apparemment vous n'utilisez pas les caractéristiques appropriées de XSLT 2.0/XPath 2.0.

Cette transformation:

<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="/*"> 
    <xsl:variable name="vs0" as="xs:decimal" 
    select="xs:decimal(num2)"/> 

    <xsl:variable name="vs1" as="xs:decimal" 
    select="xs:decimal(num3)"/> 

    s0 plain: <xsl:value-of select="$vs0"/> 
    s1 plain: <xsl:value-of select="$vs1"/> 
    test11: <xsl:value-of select="format-number($vs0, '#.#')"/> 
    test12: <xsl:value-of select="format-number($vs0, '#.###############')"/> 
    test21: <xsl:value-of select="format-number($vs1, '#.#')"/> 
    test22: <xsl:value-of select="format-number($vs1, '#.###############')"/> 

</xsl:template> 
</xsl:stylesheet> 

lorsqu'il est appliqué sur ce document XML:

<nums> 
    <num2>123456.1234</num2> 
    <num3>1234567.1234</num3> 
</nums> 

produit des résultats exacts:

s0 plain: 123456.1234 
s1 plain: 1234567.1234 
test11: 123456.1 
test12: 123456.1234 
test21: 1234567.1 
test22: 1234567.1234 

Conclusion: Lorsque vous avez besoin d'une bonne précision, essayez toujours d'utiliser le type de données xs:decimal.

+0

+1 bonne réponse! @taotree: c'est ce que j'ai écrit dans l'autre question "casting" et j'utilise "built-in data type constructors" –

+0

En fait, vous n'avez pas du tout besoin d'utiliser le format-nombre lorsque vous utilisez xs: decimal.Tout ce que vous avez à faire est de le convertir en xs: decimal et il sera toujours affiché en notation décimale (non scientifique). J'ai dû vérifier la chaîne vide car number() est pardonner mais xs: decimal() ne l'est pas. If (string-length (normalize-space ($ value))> 0) alors xs: decimal ($ value) else nombre ($ value) – mentics