Je suis dans une situation où mes fichiers XSLT doivent afficher les prix avec des décimales conditionnellement, selon que l'entrée XML contient des décimales ou non. Donc, je peux recevoir des fichiers XML avec deux types de valeurs - XML contiendra tous les prix formatés avec des décimales jusqu'à deux endroits (j'appelle celui-ci "Decimal-XML") ou les prix seront arrondis à l'entier le plus proche (j'appelle cela un "Integer-XML"). Mon problème est que j'ai besoin de refactoriser le moins possible dans les fichiers XSLT et pourtant leur permettre d'appliquer la transformation à XHTML dans le même format que l'entrée XML. Pour ce faire, je mis en œuvre et a proposé trois directives à mon équipe:XSLT Formatage décimal basé sur l'entrée XML
- Retirez toutes les fonctions
format-number()
appelle lorsque la valeur est calculée pour les calculs ou stockés dans une variable. Utiliseznumber(<value>)
à la place. Cependant, certaines conditions s'appliquent à cette règle (voir ci-dessous). - Lorsque la valeur doit être affichée, utilisez le format
format-number(<value>, '#.##')
. Cela devrait garantir que les valeurs entières ou décimales seront affichées comme initialement présentes dans le fichier XML. - Pour les balises facultatives (telles que "Discount"), utilisez la fonction
format-number(<value>, '0.00')
même si la valeur est uniquement calculée. Ceci est nécessaire car si la balise est absente, essayer d'obtenir une valeur donnera un résultatNaN
.
Voici un exemple illustratif du XSLT:
<x:stylesheet version="1.0" xmlns:x="http://www.w3.org/1999/XSL/Transform">
<x:template match="/">
<html>
<body>
<table border="1" width="60%">
<tr>
<th>Simple</th>
<th>number()</th>
<th>format-number(<expression>, '0.00')</th>
<th>format-number(<expression>, '#.##')</th>
</tr>
<x:apply-templates />
</table>
</body>
</html>
</x:template>
<x:template match="Item">
<x:variable name="qty" select="number(@numItems)" />
<x:variable name="cost" select="number(ItemCost) * $qty" />
<x:variable name="extraCharges" select="(number(Tax) + number(TxnFee)) * $qty"/>
<x:variable name="discount" select="format-number(Discount, '0.00') * $qty"/>
<tr>
<td>
<!-- Works for Integer-XML, but values in Decimal-XML are
*sometimes* rendered upto 14 decimal places. Even though Quickwatch
shows it correctly in the debugger in VS. I cannot figure out what's
special about the error cases. -->
<x:value-of select="$cost + $extraCharges - $discount"/>
</td>
<td>
<!-- Works same as the above case. -->
<x:value-of select="number($cost + $extraCharges - $discount)"/>
</td>
<td>
<!-- Works for Decimal-XML, but values in Integer-XML are always
rendered with decimal digits. -->
<x:value-of select="format-number(($cost + $extraCharges - $discount), '0.00')"/>
</td>
<td>
<!-- Works for Integer-XML, but some values in Decimal-XML are
rendered incorrectly. For example, 95.20 is rendered as 95.2;
95.00 is rendered as 95 -->
<x:value-of select="format-number(($cost + $extraCharges - $discount), '#.##')"/>
</td>
</tr>
</x:template>
</x:stylesheet>
Comme les commentaires HTML note, il fonctionne dans la plupart des cas, mais pas tous. Je voudrais utiliser une seule expression pour mettre en forme tous les prix identiques à l'entrée, plutôt que d'appliquer partout des constructions "when-else" qui nécessiteraient en outre un paramètre booléen transmis au XSLT pour déterminer le format d'affichage. L'état actuel du XSLT est que tous les nombres sont arrondis quelle que soit l'entrée, en utilisant format-number(<expression>, '0')
.
Comment accomplir ceci?
Edit: Après le commentaire de Dimitre, j'ai décidé de créer un exemple XML (et XSLT ci-dessus) de sorte que les experts peuvent essayer facilement.
XML Exemple (Celui-ci contient des décimales):
<ShoppingList>
<Item numItems="2">
<ItemCost>10.99</ItemCost>
<Tax>3.99</Tax>
<TxnFee>2.99</TxnFee>
<Discount>2.99</Discount>
</Item>
<Item numItems="4">
<ItemCost>15.50</ItemCost>
<Tax>5.50</Tax>
<TxnFee>3.50</TxnFee>
<Discount>3.50</Discount>
</Item>
</ShoppingList>
Vous avez oublié de fournir même le document XML le plus simple possible. Ce n'est pas utile. –
@Dimitre: Je n'ai pas oublié de le fournir, mais je dois avouer que je n'avais pas réalisé qu'une source XML serait requise car ce n'est pas vraiment une question de transformation. C'est une question générique sur le formatage décimal. Pourtant, je vais essayer d'en créer un si cela peut aider. – Cerebrus