juls_pro_37: XSLT 1.0 Sum

Hallo,

wie kann ich den Inhalt unter "AllowanceOrCharge_Header_002/Amount" summieren und anschließend das "_002" entfernen? Es darf dann das Element "AllowanceOrCharge_Header_002" nicht mehr im XML ausgegeben werden.

Ist:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<OrderResponse>
  <Interchange>
    <CreationDate>2021-03-02T12:28:34</CreationDate>
  </Interchange>
  <HeaderInformation>
    <AllowanceOrCharge_Header_002>
      <CalculationLevel>1</CalculationLevel>
      <Qualifier>C</Qualifier>
      <Code>FI</Code>
      <Amount>319.29</Amount>
    </AllowanceOrCharge_Header_002>
    <AllowanceOrCharge_Header_002>
      <CalculationLevel>1</CalculationLevel>
      <Qualifier>C</Qualifier>
      <Code>FI</Code>
      <Amount>327.69</Amount>
    </AllowanceOrCharge_Header_002>
    <AllowanceOrCharge_Header_002>
      <CalculationLevel>1</CalculationLevel>
      <Qualifier>C</Qualifier>
      <Code>FI</Code>
      <Amount>327.00</Amount>
    </AllowanceOrCharge_Header_002>
  </HeaderInformation>
  <LineInformation>
    <Item>
      <LineNum>1</LineNum>
    </Item>
</OrderResponse>

Soll:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<OrderResponse>
  <Interchange>
    <CreationDate>2021-03-02T12:28:34</CreationDate>
  </Interchange>
  <HeaderInformation>
    <AllowanceOrCharge_Header>
      <CalculationLevel>1</CalculationLevel>
      <Qualifier>C</Qualifier>
      <Code>FI</Code>
      <Amount>973.98</Amount>
    </AllowanceOrCharge_Header>
  </HeaderInformation>
  <LineInformation>
    <Item>
      <LineNum>1</LineNum>
    </Item>
</OrderResponse>

Hatte folgenden Ansatz:

  <xsl:template match="AllowanceOrCharge_Header">
    <xsl:copy>
      <!--copy all other nodes-->
      <xsl:apply-templates select="@* | node()"/>  
            <Amount>
               <xsl:value-of select="format-number(sum(//AllowanceOrCharge_Header_002[Code = 'FI']/Amount), '#.0000')"/>                
            </Amount>
    </xsl:copy>
  </xsl:template>

Danke & LG Julian

  1. Hallo Julian,

    wie kann ich den Inhalt unter "AllowanceOrCharge_Header_002/Amount" summieren und anschließend das "_002" entfernen? Es darf dann das Element "AllowanceOrCharge_Header_002" nicht mehr im XML ausgegeben werden.

    Dem XML fehlt zunächst </LineInformation> zur Wohlgeformtheit und damit Transformierbarkeit.

    Unter der Annahme, dass alle Inhalte außer Amount jeweils identisch sind, ergibt das die gesuchte Ausgabe. Aber vermutlich gibt es wieder abstruse nicht genannte Spezialfälle. 😉

    <?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:copy>
          <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
      </xsl:template>
    
      <xsl:template match="HeaderInformation">
        <HeaderInformation>
          <AllowanceOrCharge_Header>
            <xsl:copy-of select="AllowanceOrCharge_Header_002[1]/CalculationLevel"/>
            <xsl:copy-of select="AllowanceOrCharge_Header_002[1]/Qualifier"/>
            <xsl:copy-of select="AllowanceOrCharge_Header_002[1]/Code"/>
            <Amount>
              <xsl:value-of select="format-number(sum(//AllowanceOrCharge_Header_002[Code = 'FI']/Amount), '#.00')"/>
            </Amount>
          </AllowanceOrCharge_Header>
        </HeaderInformation>
      </xsl:template>
    
    </xsl:stylesheet>
    

    Offenbar sollen es nicht vier Nachkommastellen sein, von daher #.00 gesetzt.

    Grüße,
    Thomas

    1. danke, natürlich hast du wieder recht. Ich muss einfach bessere Testfiles zur Verfügung stellen.

      Hier funktioniert es leider nicht korrekt:

      Wie man sieht befinden sich unter "HeaderInformation" weitere Nodes und das neue "AllowanceOrCharge_Header" soll an derselben Stelle wie das vorige "AllowanceOrCharge_Header_002" stehen.

      Weiters darf die Berechnung nur stattfinden, wenn der "AllowanceOrCharge_Header_002/Code" mehrfach (mit demselben Wert) vorkommt.

      Also sprich, am besten auch, wenn der Code DI mehrfach vorkommen würde, sollte diese Berechnung stattfinden.

      <?xml version="1.0" encoding="utf-8" standalone="yes"?>
      <OrderResponse>
        <Interchange>
          <CreationDate>2021-03-02T12:28:34</CreationDate>
        </Interchange>
        <HeaderInformation>
      <ConfirmDocNum>1</ConfirmDocNum>
          <ConfirmDate>2</ConfirmDate>
          <SalesOrderReference>3</SalesOrderReference>
          <TransportDetails>
            <DeliveryReason>Standard</DeliveryReason>
          </TransportDetails>
          <AllowanceOrCharge_Header_002>
            <CalculationLevel>1</CalculationLevel>
            <Qualifier>C</Qualifier>
            <Code>DI</Code>
            <Amount>319.29</Amount>
          </AllowanceOrCharge_Header_002>
          <AllowanceOrCharge_Header_002>
            <CalculationLevel>1</CalculationLevel>
            <Qualifier>C</Qualifier>
            <Code>FI</Code>
            <Amount>327.69</Amount>
          </AllowanceOrCharge_Header_002>
          <AllowanceOrCharge_Header_002>
            <CalculationLevel>1</CalculationLevel>
            <Qualifier>C</Qualifier>
            <Code>FI</Code>
            <Amount>327.00</Amount>
          </AllowanceOrCharge_Header_002>
        </HeaderInformation>
        <LineInformation>
          <Item>
            <LineNum>1</LineNum>
          </Item>
        </LineInformation>
      </OrderResponse>
      

      Korrekt:

      <?xml version="1.0" encoding="utf-8" standalone="yes"?>
      <OrderResponse>
        <Interchange>
          <CreationDate>2021-03-02T12:28:34</CreationDate>
        </Interchange>
        <HeaderInformation>
      <ConfirmDocNum>1</ConfirmDocNum>
          <ConfirmDate>2</ConfirmDate>
          <SalesOrderReference>3</SalesOrderReference>
          <TransportDetails>
            <DeliveryReason>Standard</DeliveryReason>
          </TransportDetails>
          <AllowanceOrCharge_Header>
            <CalculationLevel>1</CalculationLevel>
            <Qualifier>C</Qualifier>
            <Code>DI</Code>
            <Amount>319.29</Amount>
          </AllowanceOrCharge_Header>
          <AllowanceOrCharge_Header>
            <CalculationLevel>1</CalculationLevel>
            <Qualifier>C</Qualifier>
            <Code>FI</Code>
            <Amount>654.69</Amount>
          </AllowanceOrCharge_Header>
        </HeaderInformation>
        <LineInformation>
          <Item>
            <LineNum>1</LineNum>
          </Item>
        </LineInformation>
      </OrderResponse>
      
      1. Hallo Julian,

        Hier funktioniert es leider nicht korrekt:

        Wie man sieht befinden sich unter "HeaderInformation" weitere Nodes und das neue "AllowanceOrCharge_Header" soll an derselben Stelle wie das vorige "AllowanceOrCharge_Header_002" stehen.

        Das Gesuchte kam bei meinem Ansatz mit den Testdaten raus. Ich bin doch nicht die wandelnde Wünschelrute.

        Weiters darf die Berechnung nur stattfinden, wenn der "AllowanceOrCharge_Header_002/Code" mehrfach (mit demselben Wert) vorkommt.

        Also sprich, am besten auch, wenn der Code DI mehrfach vorkommen würde, sollte diese Berechnung stattfinden.

        Tja, dann sind wir wie neulich bei den Gruppierungen angelangt. Bringe diese Kenntnisse gescheit zusammen.

        Grüße,
        Thomas

        1. Hätte folg. Ansatz, aber komm nicht zum gewünschten Ergebnis:

          <?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:key name="AllowanceOrCharge_Header_002" match="AllowanceOrCharge_Header_002" use="Code"/>
          
            <xsl:template match="@* | node()">
              <xsl:copy>
                <xsl:apply-templates select="@* | node()"/>
              </xsl:copy>
            </xsl:template>
          
            <xsl:template match="AllowanceOrCharge_Header_002">
              <xsl:for-each select=".[generate-id() = generate-id(key('AllowanceOrCharge_Header_002', Code)[1])]">
                <AllowanceOrCharge_Header>
                  <xsl:copy-of select="//AllowanceOrCharge_Header_002[1]/CalculationLevel"/>
                  <xsl:copy-of select="//AllowanceOrCharge_Header_002[1]/Qualifier"/>
                  <xsl:copy-of select="//AllowanceOrCharge_Header_002[1]/Code"/>
                  <Amount>
                      <xsl:value-of select="format-number(sum(//AllowanceOrCharge_Header_002/Amount), '#.00')"/>
                  </Amount>
                </AllowanceOrCharge_Header>
              </xsl:for-each>
            </xsl:template>
          
          </xsl:stylesheet>
          

          Weiter schaff ichs einfach nicht.

          Falsches Ergebnis:

          ...
          
          
                <AllowanceOrCharge_Header>
                   <CalculationLevel>1</CalculationLevel>
                   <Qualifier>C</Qualifier>
                   <Code>DI</Code>
                   <Amount>973.98</Amount>
                </AllowanceOrCharge_Header>
                <AllowanceOrCharge_Header>
                   <CalculationLevel>1</CalculationLevel>
                   <Qualifier>C</Qualifier>
                   <Code>DI</Code>
                   <Amount>973.98</Amount>
                </AllowanceOrCharge_Header>
          
          
          
          
          ...
          

          Die Summe wird nicht von den einzelnen "Codes" berechnet und mir wird auch nur ein "Code" anstatt beider ("DI" und "FI") ausgegeben.

          1. Hallo Julian,

            Die Summe wird nicht von den einzelnen "Codes" berechnet und mir wird auch nur ein "Code" anstatt beider ("DI" und "FI") ausgegeben.

            Gruppierung an sich passt, die Anwendung eher so:

            <?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:key name="AllowanceOrCharge_Header_002" match="AllowanceOrCharge_Header_002" use="Code"/>
            
              <xsl:template match="@* | node()">
                <xsl:copy>
                  <xsl:apply-templates select="@* | node()"/>
                </xsl:copy>
              </xsl:template>
            
              <xsl:template match="AllowanceOrCharge_Header_002">
                <xsl:for-each select="current()[generate-id() = generate-id(key('AllowanceOrCharge_Header_002', Code)[1])]">
                  <AllowanceOrCharge_Header>
                    <xsl:copy-of select="CalculationLevel"/>
                    <xsl:copy-of select="Qualifier"/>
                    <xsl:copy-of select="Code"/>
                    <Amount>
                      <xsl:value-of select="format-number(sum(//AllowanceOrCharge_Header_002[Code = current()/Code]/Amount), '#.00')"/>
                    </Amount>
                  </AllowanceOrCharge_Header>
                </xsl:for-each>
              </xsl:template>
            
            </xsl:stylesheet>
            

            Grüße,
            Thomas

            1. 100000 danke!!!!