xslt zum Entfernen von unnoetigen Nullkommastellen bei double und float

Wiplash4

Aktives Mitglied
Es gibt folgendes Problem. Ich muss xslt verwenden, damit ich unnoetige Nullen von einem double oder float entfernen kann.
Es sollte folgendes erreicht werden.
100 -> 100
100.00 -> 100
100.01 -> 100.01
100.10 -> 100.1
100.11 -> 100.11
100.101 -> 100.101
100.1010 -> 100.101
Wie erreiche ich das?
 
K

kneitzel

Gast
Ich habe es jetzt nicht ausprobiert, aber format-number() kann Zahlen formatieren und existiert schon ab XSLT 1.0:

Wo die Zahlen genau stecken ist ja egal - denn Du selektierst diese ja - so das selektieren klappt, hat man den Wert ja.

Ansonsten wäre die Frage: XSLT 1.0 oder 2.0 erlaubt? Und kann man eine spezifische XML Engine voraussetzen? (Xalan erlaubt z.B. das Einbinden von Typen)

Edit: Falls die '100' immer nur zu '100.' werden sollte: So einen '.' am Ende kann man ja entfernen - z.B. mit substring und string-length
(Ich bin mir nicht sicher, was z.B. ein '####0.#####' erzeugen würde).
 
Zuletzt bearbeitet von einem Moderator:

Wiplash4

Aktives Mitglied
Die Zahlen stammen von einer Java-Klasse und sind dort als Double gespeichert.
[CODE lang="java" title="Java Umwandlung durch xslt"]class Beispiel
{
Double param1;
Double param2;
}[/CODE]
. Diese Klasse wird dann in einen String umgewandelt
[CODE lang="java" title="Java Umwandlung Klasse zu String"]final StringWriter sw = new StringWriter();
JAXBContext.newInstance(c).createMarshaller().marshal(o, XMLOutputFactory.newInstance().createXMLStreamWriter(sw));
return (sw.toString());[/CODE]
Sie werden erst in Strings umgewandelt. Sie laufen durch die xslt, wo sie in strings umgewandelt werden.
Sollte es eine Java-Loesung geben, bei der man Standardmaessig beim Umwandeln einer Double in String immer die Trailing decimal places zeros entfernt werden, waere ich offen dafuer.
 
K

kneitzel

Gast
Sollte es eine Java-Loesung geben, bei der man Standardmaessig beim Umwandeln einer Double in String immer die Trailing decimal places zeros entfernt werden, waere ich offen dafuer.
Das würde dann sogar noch mehr Sinn machen (Auch wenn es durch ein xslt gehen würde):

[CODE lang="java" title="Mit DecimalFormat"] public static void formatDouble (double value) {
System.out.println(new DecimalFormat("#.#####").format(value));
}
[/CODE]

[CODE lang="java" title="Ohne das DecimalFormat"] public static void formatDouble (double value) {
if (value == (long) value) {
System.out.println("" + (long)value);
} else {
System.out.println("" + value);
}
}[/CODE]

Edit: Bei dem Format-String aufpassen - wenn da mehr Nachkommastellen sein können, dann muss man da noch # anfügen!
 

Wiplash4

Aktives Mitglied
Danke kneitzel, allerdings wuerde das fuer mich nicht funktionieren. Ist es moeglich das irgendwie ueber das JAXBContext zu machen? Vielleicht mit irgendeinem Flag?
 
K

kneitzel

Gast
Da würde ich jetzt erst einmal kurz nachhaken: Warum soll es im XML File anders dargestellt werden? Das XML File ist für mich ja erst einmal eine Speicherform der reinen Daten. Daher ist da ein 100.0 auch korrekt. Wieso stört dies? An welcher wird dies für euch zu einem Problem?

Nicht falsch verstehen - aber irgendwie drängt sich der verdacht auf, dass ihr an einer Stelle ein Problem beheben wollt, das eigentlich an einer ganz anderen Stelle besteht.

Und nach #7 (Hat sich etwas überschnitten):
Wenn Ihr da in einem xslt eine Ausgabe baut, dann wäre doch tatsächlich denkbar, da einfach ein format-number vom xslt zu nutzen. Damit bekommt ihr es dann formatiert, so wie ihr es gerne haben wollt.

Edit: Also tatsächlich einfach etwas wie <xsl:value-of select="format-number($number,'###0.#####')"/>
 

Wiplash4

Aktives Mitglied
Das xml wird spaeter weiterverwendet und da stoert das .0 einfach. Und dein Verdacht ist nicht falsch, aber dennoch soll es so geloest werden. Die .0 sind einfach unnoetig und sollen so auch nicht abgespeichert werden.
Im JAXB kommt zunaechst kein xslt zum Zuge. Die xslts kommen aber spaeter.
 
K

kneitzel

Gast
Ok, mal ein paar Gedanken zu möglichen Lösungen - aber alles aus dem Kopf heraus geschrieben und daher ggf. Fehlerbehaftet und mehr als Denkanregung!

Eine einfache Möglichkeit wäre ggf:
Java:
public class MyEntity {
    private double someValue;

    @XmlTransient
    public double getSomeValue() { return someValue; }
    
    @XmlElement(name = "someValue")
    private String getSomeValueFormatted() {
        return new DecimalFormat("#.#####").format(someValue);
    }
}
Sprich: Einfach das eigentliche Feld nicht mitnehmen (XmlTransient Annotation) und dann bei einer Methode das XmlElement setzen.


Ansonsten gäbe es auch noch den Weg über ein XmlAdapter:
Java:
public class DoubleAdapter
    extends XmlAdapter<String, Double>
{
    public Double unmarshal(String value) {
        return Double.parseDouble(value);
    }

    public String marshal(Double value) {
        return new DecimalFormat("#.#####").format(value);
    }
}

Und dann wäre die Klasse sowas:
Java:
public class MyEntity {
    @XmlElement(name = "someValue", type = String.class, required = true)
    @XmlJavaTypeAdapter(DoubleAdapter.class);
    private double someValue;
}
 

Barista

Top Contributor
Wenn es schwierig ist, in die Umwandlung von Java zu XML einzugreifen, könnte noch die Behandlung des erzeugten XML eine Lösung sein.

Suchen und Ersetzen, eventuell mit RegEx.
 

Wiplash4

Aktives Mitglied
Anscheinend hat diese Loesung einen Hacken; der Adapter soll nur in einigen Situationen passieren. Nun wundere ich mich, ob es eine andere Loesung gibt. Einen Adapter an JAXBContext Marshaller anzuhaengen scheint nicht klappen.

[CODE lang="java" title="Adapter am Marshaller"]Marshaller marshaller = context.createMarshaller();
marshaller.setAdapter(new BigDecimalAdapter());[/CODE]

Den Adapter habe ich per Annotation auch noch an die Klasse drangeklatscht, aber ohne Wirkung.

Was mache ich falsch?
 

Wiplash4

Aktives Mitglied
Kennt jemand eine Loesung, die man in xslt implementieren kann?

Kennt jemand eine Loesung, die man auf eine Klasse beschraenken kann, also die keine package-info.java braucht?
 
K

kneitzel

Gast
Wie das in xslt gehen müsste wurde doch in #3 bereits angerissen. Hast Du damit denn schon irgendwas probiert?
 

Wiplash4

Aktives Mitglied
Ja und es hat nicht geklappt. Es gab da einige Probleme, aber eines davon schien, dass die Anzahl and Stellen irgendwie limitert ist.
 
K

kneitzel

Gast
Ja und es hat nicht geklappt. Es gab da einige Probleme, aber eines davon schien, dass die Anzahl and Stellen irgendwie limitert ist.
Da wäre halt immer wichtig, Details zu erfahren. Was genau wurde wie probiert? Was war das Ergebnis?

Und bei der Serialisierung einzelner Klassen hatte ich ja als eine Option vorgeschlagen, dass über eine dedizierte Methode zu machen und das eigentliche Attribute auf Transient zu setzen. Hast Du das auch mal probiert?

Und dann wäre eine gute Idee evtl. ein kleines, ausführbares Beispiel zu erstellen anhand dessen man den aktuellen Aufbau nachvollziehen kann und dann auch Lösungsideen ausprobieren kann.
 

Wiplash4

Aktives Mitglied
Ich waere aber breit fuer eine Idee, bei der keine package-info.java verwendet wird, sondern bei JAXBContext und dem Marshaller etwas veraendert wird.
 

Oneixee5

Top Contributor
Ja und es hat nicht geklappt. Es gab da einige Probleme, aber eines davon schien, dass die Anzahl and Stellen irgendwie limitert ist.
Wenn die Formatierung nicht wie gewünscht funktioniert (was ich nachvollziehen kann), dann könnte man folgendes versuchen:

XML:
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="test.xsl"?>
<Article>
  <Title>My Article</Title>
  <Authors>
    <Author>Mr. Foo</Author>
    <Author>Mr. Bar</Author>
  </Authors>
  <Price>4.00010</Price>
  <Body>This is my article text.</Body>
</Article>
XML:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:output method="text"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="/">
    Article - <xsl:value-of select="/Article/Title"/>
    Price: <xsl:call-template name="Price">
      <xsl:with-param name="input" select="/Article/Price"/>
    </xsl:call-template>
    Authors: <xsl:apply-templates select="/Article/Authors/Author"/>
</xsl:template>

<xsl:template match="Author">
    -<xsl:value-of select="." />
</xsl:template>

<xsl:template name="Price">
  <xsl:param name="input"/>
  <xsl:choose>
    <xsl:when test="contains($input, '.') and substring($input, string-length($input), 1) = '0'">
        <xsl:call-template name="Price">
            <xsl:with-param name="input" select="substring($input, 0, string-length($input))"/>
        </xsl:call-template>
    </xsl:when>
    <xsl:otherwise>
        <xsl:value-of select="$input"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

</xsl:stylesheet>
Bash:
$ xsltproc test.xsl test.xml

    Article - My Article
    Price: 4.0001
    Authors:
    -Mr. Foo
    -Mr. Bar
 

Oneixee5

Top Contributor
Die Tagnamen spielen in dem Beispiel keine Rolle. Man kann das Template ja auch einfach für jeden Tag durchlaufen. Entscheidend ist hier, was dem Parameter input übergeben wird.
 

Wiplash4

Aktives Mitglied
Ich kenne die Tagnamen aber nicht! Ich habe das Gefühl, dass wir hier einander vorbeireden.
Ich kenne die Tagnamen nicht, ich kenne die Struktur der Klasse nicht und ich weiss nicht was sonst noch in der Klasse ist. Ich weiss nur, dass ich alle BigDecimals und Doubles der Art formatiereren will, dass
50.0 -> 50
formatiert wird.

[CODE lang="java" title="Code"]String xml =
"<message>
<value1>50.0</value1>
<value2>Test</value2>
</message>
"
executeXSLT(xml, "InputCleansing.xsl");
System.out.println(xml);[/CODE]

[CODE lang="xml" title="Ergebnis" highlight="2"]<message>
<value1>50</value1>
<value2>Test</value2>
</message>[/CODE]
. Ich kenne die genaue Strukture von message nicht!
 

Wiplash4

Aktives Mitglied
Nein. Sobald ich den Adapter als Annotation an die Klasse klatche, funktioniert er nicht. Hätte aber auch nichts gegen eine Lösung wie
[CODE lang="java" title="Lösung an jaxbContext"]jaxbContext.setAdapter(new BigDecimalAdapter());[/CODE]
. Aber auch das klappt nicht.
 

Wiplash4

Aktives Mitglied
Doch, es funktioniert mittels package-info.java. Aber ich versuche es an eine einzelne Klasse zu klatschen und nicht an das ganze Package!
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
W xslt zum Rausfiltern von Feldern in XML wenn variable gleich false XML & JSON 7
K XML und XSL bzw XSLT XML & JSON 1
R String in XSLT teilen XML & JSON 3
R Script in XSLT einbinden XML & JSON 2
K aus 2XML mache 1XML mit XSLT XML & JSON 4
G xslt Attributwerte von bestimmten Elementen XML & JSON 2
S Xslt Problem XML & JSON 2
K docBook XSLT: HTML Code Snippet in Erzeugte HTML Dokument einfügen XML & JSON 9
T XML + XSLT to PDF mit FOP-Engine XML & JSON 14
E FOP - XSLT Transformierung mit Parametern XML & JSON 4
R '&' Zeichen im XSLT XML & JSON 4
S byte array in xslt umwandeln XML & JSON 7
B XSLT collections ? XML & JSON 2
Raidri JSP Parameter an XSLT übergeben XML & JSON 2
K XSLT Frage XML & JSON 4
S Guter XSLT - Transformator XML & JSON 2
slawaweis Problem mit XSLT (wahrscheinlich ein Bug in Java 6) XML & JSON 16
G XSLT-Stylesheet XML & JSON 2
N jdom - xslt-Verweis in .xml einfügen XML & JSON 3
B anzeigen des XML+ XSLT Ergebnisses XML & JSON 21
N XML zu XSLT XML & JSON 2
N XSLT Testmethoden XML & JSON 2
M Java und XSLT: Performanz-Problem XML & JSON 5
cybermat Ergebnis einer XSLT-Tansformation als Rückgabewert erhalten XML & JSON 4
A Wie hängen SAX/DOM mit XSLT zusammen? XML & JSON 3
Noar XSLT - Element-Wrapping XML & JSON 2
byte XSLT Transformation "ohne Server" XML & JSON 6
byte XSLT Editor ? XML & JSON 7
P XSLT in Java verwenden XML & JSON 7
A XSLT oder Java? / XML-Tools XML & JSON 2
T XSLT Parameter übergeben und Ergebnis empfangen XML & JSON 1
eykarhorn JAXB namespace attribut aus rootelement entfernen XML & JSON 2
F XML unerlaubte Zeichen aus Dateien entfernen XML & JSON 9
lordcarlos JDOM und entfernen von children XML & JSON 4
Z XML auslesen, Elemente daraus entfernen und als neue XML zurückgeben XML & JSON 2
G Whitespaces zwischen den Elementen entfernen XML & JSON 14
D Wie kann ich Namespace Attribute in den Elementen entfernen? XML & JSON 2
I Namespace entfernen XML & JSON 6
D Processing Instructions aus XML entfernen XML & JSON 3
C HTML-Befehle per Java entfernen XML & JSON 7
J [Newbie] [JDOM] Element aus XML entfernen klappt nicht XML & JSON 4
R JDOM Root-Element entfernen aber Rest behalten XML & JSON 10
V XML Newlines entfernen XML & JSON 5

Ähnliche Java Themen

Neue Themen


Oben