juls_pro_37: XSLT 1.0 Kompletten Inhalt aus XML löschen

Hi,

wie kann man durch eine Bedingung (zB. wenn unter "Totals" das Segment "InvoiceTotal" nicht 0 beinhaltet, den kompletten Inhalt des XMLs entfernen?

Hätte es so probiert:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" version="1.0" encoding="UTF-8" standalone="yes" indent="yes"/>
  <xsl:strip-space elements="*" />

    <xsl:template match="/">    
        <xsl:if test="//Totals[InvoiceTotal != 0 or 0.00 or 0.0000]">       
            <xsl:apply-templates select="@* | node()"/>          
        </xsl:if>
    </xsl:template>

</xsl:stylesheet>

Jedoch bleibt immer der Header erhalten: <?xml version="1.0" encoding="UTF-8" standalone="yes"?>

XML:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<SALESINVOICE>
  <Interchange>    
    <Interchange_Control_Number>5637355402</Interchange_Control_Number>
  </Interchange>
  <HeaderInformation>
    <OrigInvoiceNumber>1</OrigInvoiceNumber>
  </HeaderInformation>
  <LineInformation>
    <Item>
      <LineNum>1</LineNum>     
    </Item>
  </LineInformation> 
  <Totals>   
    <InvoiceTotal>0.0000</InvoiceTotal>
  </Totals>
</SALESINVOICE>

Danke & LG Julian

akzeptierte Antworten

  1. Nachtrag: Wenn ich im header folgendes ändere, dann klappt es.

    alt: <xsl:output method="xml" version="1.0" encoding="UTF-8" standalone="yes" indent="yes"/>

    neu: <xsl:output method="xml" indent="yes" omit-xml-declaration="yes" />

    Jedoch habe ich nun das Problem, dass bei nicht leeren XML-files (sprich InvoiceTotal ist größer als 0) den Tag am Anfang des XMLs vermisse: "<?xml version="1.0" encoding="UTF-8" standalone="yes"?>"

    1. @@juls_pro_37

      Jedoch habe ich nun das Problem, dass bei nicht leeren XML-files (sprich InvoiceTotal ist größer als 0) den Tag am Anfang des XMLs vermisse: `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

      Und warum vermisst du den?

      Du brauchst weder die version-Angabe noch die encoding-Angabe (UTF-8 ist Standard). Die standalone-Angabe vermutlich auch nicht.

      😷 LLAP

      --
      Wenn der Faschismus wiederkehrt, wird er nicht sagen: „Hallo, ich bin der Faschismus.“ Er wird sagen: „Hört auf zu zählen! Ich habe gewonnen!“
      1. Die standalone-Angabe vermutlich auch nicht.

        Was bewirkt die standalone-Angabe generell? -> Was kann mit meinem XSLT bzw. XML passieren, wenn ich diese Angabe auf einmal weg lasse?

        1. Hallo juls_pro_37,

          Die standalone-Angabe vermutlich auch nicht. Was bewirkt die standalone-Angabe generell? -> Was kann mit meinem XSLT bzw. XML passieren, wenn ich diese Angabe auf einmal weg lasse?

          „Die XML-Deklaration kann zusätzlich eine standalone-Deklaration umfassen, falls das entsprechende Attribut gesetzt wird. In jedem Fall ist das version-Attribut und ein entsprechendes encoding-Attribut (in der Regel mit Wert "UTF-8", falls nicht im encoding-Attribut von xsl:output anders festgelegt) enthalten.“

          https://www.data2type.de/xml-xslt-xslfo/xslt/xslt-referenz/output/ war mein erster Suchtreffer.

          Bis demnächst
          Matthias

          --
          Du kannst das Projekt SELFHTML unterstützen,
          indem du bei Amazon-Einkäufen Amazon smile (Was ist das?) nutzt.
        2. @@juls_pro_37

          Was bewirkt die standalone-Angabe generell?

          Spec, Abschnitt 2.9

          😷 LLAP

          --
          Wenn der Faschismus wiederkehrt, wird er nicht sagen: „Hallo, ich bin der Faschismus.“ Er wird sagen: „Hört auf zu zählen! Ich habe gewonnen!“
      2. @@Gunnar Bittersmann

        … dass [ich] … den Tag am Anfang des XMLs vermisse:

        Ich vermisse auch manche Tage – z.B. den Tag, an dem ich im Lotto gewinn.

        Aber noch ist ja nicht aller Tage Abend.

        Und warum vermisst du den?

        Den? Heißt es nicht im Denglischen „das Tag“?

        Hier sollte es aber „die“ heißen: die XML-Deklaration. [Spec]

        😷 LLAP

        --
        Wenn der Faschismus wiederkehrt, wird er nicht sagen: „Hallo, ich bin der Faschismus.“ Er wird sagen: „Hört auf zu zählen! Ich habe gewonnen!“
  2. Hallo Julian,

    wenn für diesen Fall der gesamte Totals-Knoten entfernt werden soll, dann reicht:

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    
      <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" standalone="yes"/>
    
      <xsl:template match="@* | node()">
        <xsl:copy>
          <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
      </xsl:template>
    
      <xsl:template match="Totals[InvoiceTotal[. * 1 = 0]]"/>
    
    </xsl:stylesheet>
    

    Und zu der anderen Frage: das standalone="yes" drückt nur aus, dass das Dokument keine weiteren Abhängigkeiten hat.

    omit-xml-declaration="yes" entfernt die XML-Deklaration in der Ausgabe. Ist hier aber offenbar nicht gewollt und würde wiederum mit standalone="yes" einen Konflikt ergeben.

    Den Zusatz "* 1" braucht es eigentlich auch nicht, außer der Elementinhalt wäre als xs:string deklariert.

    Grüße,
    Thomas

    1. Nachtrag: Falls != 0 gemeint war, dann entsprechend anpassen. Hatte ich so nicht erwartet.

      Grüße,
      Thomas

    2. Und zu der anderen Frage: das standalone="yes" drückt nur aus, dass das Dokument keine weiteren Abhängigkeiten hat.

      Mit Dokument meinst du, das XML, welches nach XSLT erstellt wurde, richtig? Dann ist es für mich verständlich und wird soweit eigentlich auch nicht benötigt. -> Hatte nur die Befürchtung, dass weitere Teile (Inhalt) meines XSLT davon betroffen sein könnten und ich alle Knoten nochmals prüfen muss.

      wenn für diesen Fall der gesamte Totals-Knoten entfernt werden soll

      In meinem Fall muss ALLES sprich der komplette Inhalt entfernt werden, nicht nur der Knoten totals. -> Sprich, wenn der Betrag unter InvoiceTotal 0.000 ist, sollte im besten Fall gar kein XML erzeugt werden und falls doch soll kein Inhalt erstellt werden.

      Danke!!

      LG Julian

      1. Hallo Julian,

        wenn für diesen Fall der gesamte Totals-Knoten entfernt werden soll In meinem Fall muss ALLES sprich der komplette Inhalt entfernt werden, nicht nur der Knoten totals. -> Sprich, wenn der Betrag unter InvoiceTotal 0.000 ist, sollte im besten Fall gar kein XML erzeugt werden und falls doch soll kein Inhalt erstellt werden.

        Ein Ansatz, der im 0-Fall <root/> ausgibt (ginge auch nur mit einem xsl:if und dann bleibt die Ausgabe bis auf die Deklaration leer):

        <?xml version="1.0" encoding="UTF-8"?>
        <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        
          <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
        
          <xsl:template match="@* | node()">
            <xsl:choose>
              <xsl:when test="//Totals/InvoiceTotal != 0">
                <xsl:copy>
                  <xsl:apply-templates select="@* | node()"/>
                </xsl:copy>
              </xsl:when>
              <xsl:otherwise>
                <root/>
              </xsl:otherwise>
            </xsl:choose>
          </xsl:template>
        
        </xsl:stylesheet>
        

        Mit XSLT 2.0/3.0 ließe sich xsl:result-document bemühen und ggf. gar keine Ausgabe erzeugen.

        Grüße,
        Thomas

        1. Thx again Thomas :)

          LG Julian

        2. bin durch deinen Vorschlag auch auf folg. Lösung gestoßen.

          Scheint auch zu funktionieren:

            <xsl:stylesheet version="1.0"
               xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
          
           <xsl:output method="xml" indent="yes" encoding="UTF-8"/>
           
            <xsl:strip-space elements="*" />
          
              <xsl:template match="/">   
                  <xsl:choose>
                      <xsl:when test="//Totals[InvoiceTotal = 0 or 0.00 or 0.0000]"></xsl:when>
                      <xsl:when test="//HeaderInformation[InvoiceType = 'CREDITNOTE']"></xsl:when>
                          <xsl:otherwise> <xsl:apply-templates select="@* | node()"/></xsl:otherwise>
                  </xsl:choose>
              </xsl:template>
          
          1. Hallo Julian,

            <xsl:when test="//Totals[InvoiceTotal = 0 or 0.00 or 0.0000]"
            

            Die 0-Bedingung wird gefunden, die beiden anderen sind unnötig und auch fehlerhaft:

            test="//Totals[InvoiceTotal = 0 or InvoiceTotal = 0.00 or InvoiceTotal = 0.0000]

            Belasse es bei 0. '0.00' und '0.0000' wären denkbar, sind aber eben redundant, außer man möchte explizit auf diese Strings prüfen.

            Grüße,
            Thomas