Problem mit XSL an ein Element zu kommen

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Problem mit XSL an ein Element zu kommen

    Hallo,

    ich stehe vor folgendem Problem. Ich bekomme von einem Kunden eine XML Datei die folgendes Element aufweisst:

    Quellcode

    1. <weitere_information>
    2. <nummer>xxxxxxxx</nummer>
    3. <info_nr>1
    4. <absatz_nr>1
    5. <gueltig_von>2004-11-22</gueltig_von>
    6. <gueltig_bis>2010-12-31</gueltig_bis>
    7. <info_txt>Information 1 Absatz 1</info_txt>
    8. </absatz_nr>
    9. </info_nr>
    10. <info_nr>2
    11. <absatz_nr>1
    12. <gueltig_von>2005-05-30</gueltig_von>
    13. <gueltig_bis>2006-08-04</gueltig_bis>
    14. <info_txt>Information 2 Absatz 1</info_txt>
    15. </absatz_nr>
    16. <absatz_nr>2
    17. <gueltig_von>2005-12-02</gueltig_von>
    18. <gueltig_bis>2006-08-04</gueltig_bis>
    19. <info_txt>Information 1 Absatz 3</info_txt>
    20. </absatz_nr>
    21. <absatz_nr>3
    22. <gueltig_von>2006-07-12</gueltig_von>
    23. <gueltig_bis>2007-01-06</gueltig_bis>
    24. <info_txt>Information 1 Absatz 3</info_txt>
    25. </absatz_nr>
    26. </info_nr>
    27. </weitere_information>
    Alles anzeigen


    Das ganze möchte ich in eine CSV Datei wandeln. Mit folgendem XSL Code komme ich schon ziemlich an alle Elemente

    Quellcode

    1. <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    2. <xsl:output method="text" indent="yes" media-type="text/plain" encoding="latin1"/>
    3. <xsl:template match="/">
    4. <xsl:for-each select="weitere_information">
    5. <xsl:variable name="nr"><xsl:value-of select="nummer"/></xsl:variable>
    6. <xsl:for-each select="info_nr">
    7. <xsl:for-each select="absatz_nr">
    8. <xsl:value-of select="$nr"/>;;;"<xsl:value-of select="gueltig_von"/>";"<xsl:value-of select="gueltig_bis"/>";"<xsl:value-of select="info_txt"/>";
    9. </xsl:for-each>
    10. </xsl:for-each>
    11. </xsl:for-each>
    12. </xsl:template>
    13. </xsl:stylesheet>
    Alles anzeigen


    Allerdings benötige ich noch die jeweiligen laufenden Nummern "info_nr" sowie "absatz_nr". Wenn ich mir nur deren Inhalt mit

    Quellcode

    1. <xsl:value-of select="."/>


    ausgebe, erhalte ich auch nochmal alle darin enthaltenden Elemente. Allerdings brauche ich ja nur den Zahlenwert.

    Hat da jemand eine Idee? Vielleicht blicke ich auch einfach gerade nicht durch.

    Danke!
  • Vielen Dank für die schnelle Antwort. Habe das mal probiert. Wenn ich jedoch "." verwende bekomme ich immer den kompletten Inhalt zurück, also leider nicht nur die ZAHL.

    Quellcode

    1. <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    2. <xsl:output method="text" indent="yes" media-type="text/plain" encoding="latin1"/>
    3. <xsl:template match="/">
    4. <xsl:for-each select="weitere_information">
    5. <xsl:variable name="nr"><xsl:value-of select="nummer"/></xsl:variable>
    6. <xsl:for-each select="info_nr">
    7. <xsl:variable name="inf_nr"><xsl:apply-templates/></xsl:variable>
    8. <xsl:for-each select="absatz_nr">
    9. <xsl:value-of select="$nr"/>;<xsl:value-of select="$inf_nr"/>;;"<xsl:value-of select="gueltig_von"/>";"<xsl:value-of select="gueltig_bis"/>";"<xsl:value-of select="info_txt"/>";
    10. </xsl:for-each>
    11. </xsl:for-each>
    12. </xsl:for-each>
    13. </xsl:template>
    14. <xsl:template match="info_nr/text() | absatz_nr/text()">
    15. <xsl:value-of select="."/>
    16. </xsl:template>
    17. </xsl:stylesheet>
    Alles anzeigen


    Das Ergebnis ist dann immer

    Quellcode

    1. xxxxxxxx;1
    2. 1
    3. 2004-11-22
    4. 2010-12-31
    5. Information 1 Absatz 1
    6. ;;"2004-11-22";"2010-12-31";"Information 1 Absatz 1";
    7. xxxxxxxx;2
    8. 1
    9. 2005-05-30
    10. 2006-08-04
    11. Information 2 Absatz 1
    12. ;;"2005-05-30";"2006-08-04";"Information 2 Absatz 1";
    Alles anzeigen


    Also an der Stelle packt er mir immer den kompletten Inhalt nur ohne Tags rein.

    Bin leider auf dem Gebiet noch recht neu. Kann sich natürlich auch um einen dummen Denkfehler handeln. Das Ergebnis sollte natürlich wie folgt aussehen

    Quellcode

    1. xxxxxxxx;1;;"2004-11-22";"2010-12-31";"Information 1 Absatz 1";
    2. xxxxxxxx;2;;"2005-05-30";"2006-08-04";"Information 2 Absatz 1";


    und in der dritten Spalte natürlich später die absatz_nr, aber das wird dann der selbe Schritt sein.

    Ach so, ich verwende den "xsltproc" unter bash (suse 9.3). Nicht das es irgendwie daran liegt, oder?
  • Unter der Voraussetzung, dass der Wert hinter "info_nr" immer eine Zahl ist,m funktioniert der folgende Code:

    Quellcode

    1. <?xml version="1.0"?>
    2. <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    3. <xsl:output method="text" indent="yes" media-type="text/plain" encoding="latin1"/>
    4. <xsl:template match="/">
    5. <xsl:apply-templates/>
    6. </xsl:template>
    7. <xsl:template match="weitere_information/info_nr/absatz_nr">
    8. <xsl:value-of select="../../nummer"/>
    9. <xsl:text>;</xsl:text>
    10. <xsl:value-of select="number (../text())"/>
    11. <xsl:text>;;"</xsl:text>
    12. <xsl:value-of select="gueltig_von"/>
    13. <xsl:text>";"</xsl:text>
    14. <xsl:value-of select="gueltig_bis"/>
    15. <xsl:text>";"</xsl:text>
    16. <xsl:value-of select="info_txt"/>
    17. <xsl:text>";
    18. </xsl:text>
    19. </xsl:template>
    20. <!-- Muss haendisch rausgefiltert werden -->
    21. <xsl:template match="text()" />
    22. </xsl:stylesheet>
    Alles anzeigen


    Ich habe versucht, die Regeln auf ein Minimum zu beschränken, du musst allerdings wissen, wie das Default-Verhalten ist:
    text () wird normalerweise immer in die Ausgabe kopiert, deshalb muss man dass mit einem leeren Template unterbinden
    Bei Elementen macht der XSLT-Parser immer automatisch ein traversieren in Dokumentenorder, deshlab brauch man die Zwischenregeln nicht angeben.

    Mit ".." kommst du eine Ebene nach oben, und die Funktion "number (...)" konvertiert einen String in eine Nummer.
    Wenn du die XML-Datei wie folgt erstellst:

    Quellcode

    1. <info_nr>1<absatz_nr>1<gueltig_von>2004-11-22</gueltig_von><gueltig_bis>2010-12-31</gueltig_bis><info_txt>Information1Absatz1</info_txt></absatz_nr></info_nr>

    d.h. ohne die Leerzeilen, dann kannst du dir den Aufruf der "number" Funktion sparen.

    hth