juls_pro_37: XSLT 1.0 Nummerierung (count)

Hi, hätte wieder eine Frage zur fortlaufenden Berechnung.

Benötige ein neues Segment "LineNumSalesLine" - wenn nicht vorhanden.

Dieses Segment soll alle bestehenden "LineNumSalesLine" zählen und fortlaufend nummerieren. (mein Problem ist LineNum 4)

XML:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<OrderResponse>
  <Interchange>    
    <Interchange_Control_Number>5637334332</Interchange_Control_Number>
  </Interchange>
  <HeaderInformation>    
  </HeaderInformation>
  <LineInformation>
    <Item>
      <LineNum>1</LineNum>
      <SupplierArticleNumber>test1</SupplierArticleNumber>
      <OrigSupplierArticleNumber>test1</OrigSupplierArticleNumber>
      <BuyerArticleNumber>abc</BuyerArticleNumber>     
      <LineNumSalesLine>1</LineNumSalesLine>
    </Item>    
    <Item>
      <LineNum>2</LineNum>
      <SupplierArticleNumber>test2</SupplierArticleNumber>
    </Item>
    <Item>
      <LineNum>3</LineNum>
      <SupplierArticleNumber>test3</SupplierArticleNumber>
      <OrigSupplierArticleNumber>def</OrigSupplierArticleNumber>
      <LineNumSalesLine>3</LineNumSalesLine> 
    </Item>
    <Item>
      <LineNum>4</LineNum>
      <SupplierArticleNumber>4</SupplierArticleNumber>      
    </Item>
  </LineInformation>  
</OrderResponse>

XSLT:

 <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="Item[not(LineNumSalesLine)]">
        <xsl:copy>        
            <!--copy all other nodes-->
            <xsl:apply-templates select="@* | node()"/>
                <LineNumSalesLine>
                    <xsl:value-of select="count(//Item/LineNumSalesLine) + 1"/>                 
                </LineNumSalesLine>
	    </xsl:copy>
</xsl:template>
  
    <!-- Identity-Template für die nicht explizit benannten Elemente -->
  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template> 

 <xsl:template match="*[not(@*|*|comment()|processing-instruction()) and normalize-space()='']"/>

</xsl:stylesheet>

korrekt sollte es so aussehen:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<OrderResponse>
   <Interchange>
      <Interchange_Control_Number>5637334332</Interchange_Control_Number>
   </Interchange>
   <LineInformation>
      <Item>
         <LineNum>1</LineNum>
         <SupplierArticleNumber>test1</SupplierArticleNumber>
         <OrigSupplierArticleNumber>test1</OrigSupplierArticleNumber>
         <BuyerArticleNumber>abc</BuyerArticleNumber>
         <LineNumSalesLine>1</LineNumSalesLine>
      </Item>
      <Item>
         <LineNum>2</LineNum>
         <SupplierArticleNumber>test2</SupplierArticleNumber>
         <LineNumSalesLine>3</LineNumSalesLine>
      </Item>
      <Item>
         <LineNum>3</LineNum>
         <SupplierArticleNumber>test3</SupplierArticleNumber>
         <OrigSupplierArticleNumber>def</OrigSupplierArticleNumber>
         <LineNumSalesLine>3</LineNumSalesLine>
      </Item>
      <Item>
         <LineNum>4</LineNum>
         <SupplierArticleNumber>4</SupplierArticleNumber>
         <LineNumSalesLine>4</LineNumSalesLine>
      </Item>
   </LineInformation>
</OrderResponse>

Danke & LG Julian

akzeptierte Antworten

  1. Hallo Julian,

    Benötige ein neues Segment "LineNumSalesLine" - wenn nicht vorhanden.

    Dieses Segment soll alle bestehenden "LineNumSalesLine" zählen und fortlaufend nummerieren. (mein Problem ist LineNum 4)

    Du möchtest für LineNumSalesLine: 1 | 3 | 3 | 4. Dann könnte das im entsprechenden Template helfen:

    <LineNumSalesLine>
      <xsl:value-of select="count(preceding::LineNumSalesLine) +
        count(not(preceding::LineNumSalesLine)) + 1"/>
    </LineNumSalesLine>
    

    Grüße,
    Thomas

    1. Hi,

      danke dir. Leider erhalte ich hier einen Fehler: Ambiguous rule match for /OrderResponse[1] Matches both "@ | node()" on line -1 of and "node()|@" on line -1 of Recoverable error

      Der erste Teil funktioniert (count(preceding::LineNumSalesLine)), wenn ich aber diesen Teil (count(not(preceding::LineNumSalesLine))) anwende kommt die o.s. Meldung.

      Bitte um Hilfe.

      LG Julian

      1. Hallo Julian,

        danke dir. Leider erhalte ich hier einen Fehler: Ambiguous rule match for /OrderResponse[1] Matches both "@ | node()" on line -1 of and "node()|@" on line -1 of Recoverable error

        Teste immer zuerst mit Saxon-HE, dort lief das durch. MSXML zeigte aber das genannte Problem auch.

        Dann etwas spezifischer:

        <LineNumSalesLine>
          <xsl:value-of select="count(preceding::LineNumSalesLine) + 
            count(//Item[not(preceding::LineNumSalesLine)]) + 1"/>
        </LineNumSalesLine>
        

        Grüße,
        Thomas

        1. Hi Thomas,

          irgendwie habe ich gerade große Schwierigkeiten und weiß nicht woran es liegt.

          Kann ich dir auf irgendeinem Weg mein komplettes XML und XSLT senden?

          Ansonsten muss ich alle nicht öffentlichen Daten abändern und bereitstellen.

          Entweder stehe ich am Schlauch oder hab einen Fehler beim XML in diesem Beitrag gemacht. :S

          LG Julian

          1. Hallo Julian,

            Kann ich dir auf irgendeinem Weg mein komplettes XML und XSLT senden?

            Nö. hier gefragt, hier besprochen.

            Entweder stehe ich am Schlauch oder hab einen Fehler beim XML in diesem Beitrag gemacht. :S

            Meine Anpassung erzeugt exakt die gewünschte Ausgabe mit den Werten für LineNumSalesLine: 1 | 3 | 3 | 4.

            <xsl:template match="Item[not(LineNumSalesLine)]">
              <xsl:copy>
                <!--copy all other nodes-->
                <xsl:apply-templates select="@* | node()"/>
                <LineNumSalesLine>
                  <xsl:value-of select="count(preceding::LineNumSalesLine) +
                    count(//Item[not(preceding::LineNumSalesLine)]) + 1"/>
                </LineNumSalesLine>
              </xsl:copy>
            </xsl:template>
            

            Falls das 1 | 2 | 3 | 4 lauten sollte, würde bereits position() reichen.

            Grüße,
            Thomas

            1. ok ich versuchs nochmal mit einem neuen XML und XSLT, bitte findest du die Lösung :)

              XML:

              <?xml version="1.0" encoding="utf-8" standalone="yes"?>
              <OrderResponse>
                <Interchange>    
                  <Interchange_Control_Number>5637334349</Interchange_Control_Number>
                </Interchange>
                <HeaderInformation>
                  <ConfirmDocNum>SO0001084-3</ConfirmDocNum>    
                </HeaderInformation>
                <LineInformation>
                  <Item>
                    <LineNum>1</LineNum>      
                    <SupplierArticleNumber>P0003975A</SupplierArticleNumber>
                    <OrigSupplierArticleNumber>P0003975A</OrigSupplierArticleNumber>
                    <BuyerArticleNumber>S02754</BuyerArticleNumber>
                    <LineNumSalesLine>1</LineNumSalesLine>
                  </Item>
                  <Item>
                    <LineNum>2</LineNum>      
                    <SupplierArticleNumber>P0090610</SupplierArticleNumber>
                    <OrigSupplierArticleNumber>P0090610</OrigSupplierArticleNumber>
                    <BuyerArticleNumber>S29648</BuyerArticleNumber>
                    <LineNumSalesLine>2</LineNumSalesLine>
                  </Item>
                  <Item>
                    <LineNum>3</LineNum>     
                    <SupplierArticleNumber>P0090631</SupplierArticleNumber>
                    <OrigSupplierArticleNumber>P0090631</OrigSupplierArticleNumber>
                    <BuyerArticleNumber>S29649</BuyerArticleNumber>
                    <LineNumSalesLine>3</LineNumSalesLine>
                  </Item>
                  <Item>
                    <LineNum>4</LineNum>      
                    <SupplierArticleNumber>P0090611</SupplierArticleNumber>
                    <OrigSupplierArticleNumber>P0090611</OrigSupplierArticleNumber>
                    <BuyerArticleNumber>S29652</BuyerArticleNumber>
                    <LineNumSalesLine>4</LineNumSalesLine>
                  </Item>
                  <Item>
                    <LineNum>5</LineNum>
                    <SupplierArticleNumber>P0090615</SupplierArticleNumber>
                    <OrigSupplierArticleNumber>P0090615</OrigSupplierArticleNumber>
                    <BuyerArticleNumber>S29657</BuyerArticleNumber>
                    <LineNumSalesLine>5</LineNumSalesLine>
                  </Item>
                  <Item>
                    <LineNum>6</LineNum>
                    <SupplierArticleNumber>P0090635</SupplierArticleNumber>
                    <OrigSupplierArticleNumber>P0090635</OrigSupplierArticleNumber>
                    <BuyerArticleNumber>S29664</BuyerArticleNumber>
                    <LineNumSalesLine>6</LineNumSalesLine>
                  </Item>
                  <Item>
                    <LineNum>7</LineNum>
                    <SupplierArticleNumber>P0003200A</SupplierArticleNumber>
                    <OrigSupplierArticleNumber>P0003200A</OrigSupplierArticleNumber>
                    <LineNumSalesLine>7</LineNumSalesLine>
                    <LineText />
                  </Item>
                  <Item>
                    <LineNum>8</LineNum>
                    <SupplierArticleNumber>P0001555</SupplierArticleNumber>
                  </Item>
                  <Item>
                    <LineNum>9</LineNum>
                    <SupplierArticleNumber>P0009051</SupplierArticleNumber>
                  </Item>
                  <Item>
                    <LineNum>10</LineNum>
                    <SupplierArticleNumber>P0009068</SupplierArticleNumber>
                  </Item>
                  <Item>
                    <LineNum>11</LineNum>
                    <SupplierArticleNumber>P0075511</SupplierArticleNumber>
                  </Item>
                  <Item>
                    <LineNum>12</LineNum>
                    <SupplierArticleNumber>P0001113</SupplierArticleNumber>
                  </Item>
                  <Item>
                    <LineNum>13</LineNum>
                    <SupplierArticleNumber>P00MESD2</SupplierArticleNumber>
                    <OrigSupplierArticleNumber>EDIPER</OrigSupplierArticleNumber>
                    <LineNumSalesLine>9</LineNumSalesLine>
                    <LineText />
                  </Item>
                  <Item_001>
                    <SupplierArticleNumber>EDIPER</SupplierArticleNumber>
                    <BuyerArticleNumber>P00MESD2</BuyerArticleNumber>
                    <LineNumSalesLine>9</LineNumSalesLine>
                  </Item_001>
                  <Item_002>
                    <GTIN>3660965369511</GTIN>
                    <SupplierArticleNumber>BKPROL150</SupplierArticleNumber>
                    <LineNumSalesLine>8</LineNumSalesLine>
                    <LineText_002 />
                  </Item_002>
                </LineInformation>      
                </OrderResponse>
              

              XSLT:

               <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="Item_001"> 	   
               <xsl:element name="Item">
                         <LineChange>
                  		    <xsl:choose>     
                                   <!-- Wert 7 (Cancel), wenn es Artikel gibt in denen EDI vorkommt (EDIPER/EDICIL) -->
                                   <xsl:when test="SupplierArticleNumber[contains(., 'EDI')]">7</xsl:when>                     
              			    </xsl:choose>
              		    </LineChange>
                              <!--create new node LineNum with counter for Item_001 -->
                  		<LineNum>
                              <xsl:number value="position()" />                 
                          </LineNum>
              	<!--copy all other nodes-->
              	<xsl:apply-templates select="@* | node()"/>                
              	<!-- Positionstext, wenn es Abweichungen zwischen bestellten und bestätigten Artikel gibt  -->
                      <xsl:choose>
                  			<xsl:when test="SupplierArticleNumber[contains(., 'EDI')]">
                  				<LineText>
              						<Qualifier>ZZZ</Qualifier>						
              						<Text>Article remplace par <xsl:value-of select="BuyerArticleNumber"/></Text>	
              					</LineText>
              				</xsl:when>
                      </xsl:choose>   
              </xsl:element>
                 </xsl:template>
                 
                <!-- Delete Item_001/BuyerArticleNumber-->
                <xsl:template match="Item_001/BuyerArticleNumber"/>
                
                <xsl:template match="Item_002">        
               <xsl:element name="Item">
                      <!-- Wert 7 (Cancelled_Item) -->
                         <LineChange>7</LineChange>
                              <!--create new node LineNum with counter for Item_001 -->
                      	<LineNum>
                              <xsl:number value="position()" />                 
                          </LineNum>
              	<!--copy all other nodes-->
              	<xsl:apply-templates select="@* | node()"/>
              </xsl:element>
                 </xsl:template>
              
                  <xsl:template match="LineText_002">        
                      <xsl:element name="LineText">       
              	<!--copy all other nodes-->
              	<xsl:apply-templates select="@* | node()"/>
                      </xsl:element>
                  </xsl:template>
                 
              
                 
                 <xsl:template match="Item[not(LineNumSalesLine)]">
                <xsl:copy>
                  <!--copy all other nodes-->
                  <xsl:apply-templates select="@* | node()"/>
                  <LineNumSalesLineTest>
                    <xsl:value-of select="count(preceding::LineNumSalesLine) +
                      count(//Item[not(preceding::LineNumSalesLine)]) + 1"/>
                  </LineNumSalesLineTest>
                </xsl:copy>
              </xsl:template>
              
                  <!-- Identity-Template für die nicht explizit benannten Elemente -->
                <xsl:template match="@* | node()">
                  <xsl:copy>
                    <xsl:apply-templates select="@* | node()"/>
                  </xsl:copy>
                </xsl:template>
              
                
                    <!-- delete empty nodes -->
              	<xsl:template match="node()|@*">
              		<xsl:copy>
              			<xsl:apply-templates select="node()|@*"/>
              		</xsl:copy>
              	</xsl:template>
              
               <xsl:template match="*[not(@*|*|comment()|processing-instruction()) and normalize-space()='']"/>
              
              </xsl:stylesheet>
              

              LG Julian

              1. Hallo Julian,

                ok ich versuchs nochmal mit einem neuen XML und XSLT, bitte findest du die Lösung :)

                Zu welchem Problem? Es bleibt unklar, welchem Muster die LineNumSalesLineTest-Nummern folögen sollen.

                Grüße,
                Thomas

                1. hi, dachte so wäre es einfacher zu erkennen. wenn ich Test bei der LineNumSalesLine hinzufüge.

                  Bei all den Lines mit <LineNumSalesLineTest> muss gezählt werden, wie viele <LineNumSalesLine> vorhanden sind und immer fortlaufend nummerieren; bekomme aber immer nur den Wert "9" ausgegeben.

                  Gezählt werden soll also die Anzahl der <LineNumSalesLine> unter dem Knoten "Item". (diese ist 8x vorhanden)

                  So sollte es korrekt aussehen: (Beispiel: LineNum 8 hat somit die LineNumSalesLineTest 9, LineNum9 hat die LineSumSalesLineTest 10,...)

                  XML:

                  <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
                  <OrderResponse>
                     <Interchange>
                        <Interchange_Control_Number>5637334349</Interchange_Control_Number>
                     </Interchange>
                     <HeaderInformation>
                        <ConfirmDocNum>SO0001084-3</ConfirmDocNum>
                     </HeaderInformation>
                     <LineInformation>
                        <Item>
                           <LineNum>1</LineNum>
                           <SupplierArticleNumber>P0003975A</SupplierArticleNumber>
                           <OrigSupplierArticleNumber>P0003975A</OrigSupplierArticleNumber>
                           <BuyerArticleNumber>S02754</BuyerArticleNumber>
                           <LineNumSalesLine>1</LineNumSalesLine>
                        </Item>
                        <Item>
                           <LineNum>2</LineNum>
                           <SupplierArticleNumber>P0090610</SupplierArticleNumber>
                           <OrigSupplierArticleNumber>P0090610</OrigSupplierArticleNumber>
                           <BuyerArticleNumber>S29648</BuyerArticleNumber>
                           <LineNumSalesLine>2</LineNumSalesLine>
                        </Item>
                        <Item>
                           <LineNum>3</LineNum>
                           <SupplierArticleNumber>P0090631</SupplierArticleNumber>
                           <OrigSupplierArticleNumber>P0090631</OrigSupplierArticleNumber>
                           <BuyerArticleNumber>S29649</BuyerArticleNumber>
                           <LineNumSalesLine>3</LineNumSalesLine>
                        </Item>
                        <Item>
                           <LineNum>4</LineNum>
                           <SupplierArticleNumber>P0090611</SupplierArticleNumber>
                           <OrigSupplierArticleNumber>P0090611</OrigSupplierArticleNumber>
                           <BuyerArticleNumber>S29652</BuyerArticleNumber>
                           <LineNumSalesLine>4</LineNumSalesLine>
                        </Item>
                        <Item>
                           <LineNum>5</LineNum>
                           <SupplierArticleNumber>P0090615</SupplierArticleNumber>
                           <OrigSupplierArticleNumber>P0090615</OrigSupplierArticleNumber>
                           <BuyerArticleNumber>S29657</BuyerArticleNumber>
                           <LineNumSalesLine>5</LineNumSalesLine>
                        </Item>
                        <Item>
                           <LineNum>6</LineNum>
                           <SupplierArticleNumber>P0090635</SupplierArticleNumber>
                           <OrigSupplierArticleNumber>P0090635</OrigSupplierArticleNumber>
                           <BuyerArticleNumber>S29664</BuyerArticleNumber>
                           <LineNumSalesLine>6</LineNumSalesLine>
                        </Item>
                        <Item>
                           <LineNum>7</LineNum>
                           <SupplierArticleNumber>P0003200A</SupplierArticleNumber>
                           <OrigSupplierArticleNumber>P0003200A</OrigSupplierArticleNumber>
                           <LineNumSalesLine>7</LineNumSalesLine>
                        </Item>
                        <Item>
                           <LineNum>8</LineNum>
                           <SupplierArticleNumber>P0001555</SupplierArticleNumber>
                           <LineNumSalesLineTest>9</LineNumSalesLineTest>
                        </Item>
                        <Item>
                           <LineNum>9</LineNum>
                           <SupplierArticleNumber>P0009051</SupplierArticleNumber>
                           <LineNumSalesLineTest>10</LineNumSalesLineTest>
                        </Item>
                        <Item>
                           <LineNum>10</LineNum>
                           <SupplierArticleNumber>P0009068</SupplierArticleNumber>
                           <LineNumSalesLineTest>11</LineNumSalesLineTest>
                        </Item>
                        <Item>
                           <LineNum>11</LineNum>
                           <SupplierArticleNumber>P0075511</SupplierArticleNumber>
                           <LineNumSalesLineTest>12</LineNumSalesLineTest>
                        </Item>
                        <Item>
                           <LineNum>12</LineNum>
                           <SupplierArticleNumber>P0001113</SupplierArticleNumber>
                           <LineNumSalesLineTest>13</LineNumSalesLineTest>
                        </Item>
                        <Item>
                           <LineNum>13</LineNum>
                           <SupplierArticleNumber>P00MESD2</SupplierArticleNumber>
                           <OrigSupplierArticleNumber>EDIPER</OrigSupplierArticleNumber>
                           <LineNumSalesLine>9</LineNumSalesLine>
                        </Item>
                        <Item>
                           <LineChange>7</LineChange>
                           <LineNum>14</LineNum>
                           <SupplierArticleNumber>EDIPER</SupplierArticleNumber>
                           <LineNumSalesLine>9</LineNumSalesLine>
                           <LineText>
                              <Qualifier>ZZZ</Qualifier>
                              <Text>Article remplace par P00MESD2</Text>
                           </LineText>
                        </Item>
                        <Item>
                           <LineChange>7</LineChange>
                           <LineNum>15</LineNum>
                           <GTIN>3660965369511</GTIN>
                           <SupplierArticleNumber>BKPROL150</SupplierArticleNumber>
                           <LineNumSalesLine>8</LineNumSalesLine>
                        </Item>
                     </LineInformation>
                  </OrderResponse>
                  
                  

                  LG Julian

                  1. Hallo Julian,

                    So sollte es korrekt aussehen: (Beispiel: LineNum 8 hat somit die LineNumSalesLineTest 9, LineNum9 hat die LineSumSalesLineTest 10,...)

                    Ich sehe nur noch diesen Ansatz:

                    Wenn LineNumSalesLine fehlt, dann dessen Inhalt = LineNum-Wert + 1.

                    <xsl:template match="Item[not(LineNumSalesLine)]">
                      <xsl:copy>
                        <!--copy all other nodes-->
                        <xsl:apply-templates select="@* | node()"/>
                        <LineNumSalesLineTest>
                          <xsl:value-of select="LineNum + 1"/>
                        </LineNumSalesLineTest>
                      </xsl:copy>
                    </xsl:template>
                    

                    Klinke mich jetzt hier aus.

                    Grüße,
                    Thomas

                    1. danke :) die lösung ist in diesem fall doch näher und einfach als gedacht. :)

                      kannst du mir bitte nur bei gelegenheit erklären, warum deine berechnung hier nicht möglich war/ist? vl. verstehe ich es dann etwas besser.

                      <LineNumSalesLine>
                        <xsl:value-of select="count(preceding::LineNumSalesLine) +
                          count(//Item[not(preceding::LineNumSalesLine)]) + 1"/>
                      </LineNumSalesLine>
                      

                      lg julian

                      1. Hallo Julian,

                        kannst du mir bitte nur bei gelegenheit erklären, warum deine berechnung hier nicht möglich war/ist? vl. verstehe ich es dann etwas besser.

                        Diese passte zumindest auf das zuerst gepostete Beispiel. Die späteren Daten waren dann etwas anders organisiert bzw. ich bin zufällig auf ein zunächst gewünschtes Ergebnis gekommen, ohne das Problem vollständig verstanden zu haben.

                        Dir zu folgen ist ja auch nicht ganz einfach. 😉

                        Grüße,
                        Thomas

                        1. Dir zu folgen ist ja auch nicht ganz einfach. 😉

                          das stimmt :)