juls_pro_37: XSLT 1.0 zusammenführen mehrerer Knoten

Hi,

wie kann ich die Knoten "HeaderText" mit dem selben "Qualifier" (in meinem Fall "PUR") zusammenführen zu einem Knoten?

derzeit:

<?xml version="1.0"?>
<SALESORDER>
    <Interchange>		
		<BGM>220</BGM>
		<HeaderInformation>			
			<HeaderText>
				<Qualifier>PUR</Qualifier>
				<Text>Test:</Text>
			</HeaderText>
			<HeaderText>
				<Qualifier>PUR</Qualifier>
				<Text>Anlieferung</Text>
			</HeaderText>
			<HeaderText>
				<Qualifier>PUR</Qualifier>
				<Text>Auslieferung</Text>
			</HeaderText>
			<RFF_Header>
				<Qualifier>COF</Qualifier>
				<Text>00</Text>
			</RFF_Header>			
			<LineItem>
				<Line>1</Line>				
			</LineItem>
		</HeaderInformation>
	</Interchange>
</SALESORDER>

Korrekt:

<?xml version="1.0"?>
<SALESORDER>
    <Interchange>		
		<BGM>220</BGM>
		<HeaderInformation>			
			<HeaderText>
				<Qualifier>PUR</Qualifier>
				<Text>Test: Anlieferung Auslieferung</Text>
			</HeaderText>			
			<RFF_Header>
				<Qualifier>COF</Qualifier>
				<Text>00</Text>
			</RFF_Header>			
			<LineItem>
				<Line>1</Line>				
			</LineItem>
		</HeaderInformation>
	</Interchange>
</SALESORDER>Quelltext hier

Danke & LG Julian

akzeptierte Antworten

  1. Hab das jetzt für den Kopfbereich (HeaderText) gelöst, jedoch scheitere ich auf der Line. (LineText)

    XML:

    <?xml version="1.0"?>
    <SALESORDER>
        <Interchange>		
    		<BGM>220</BGM>
    		<HeaderInformation>			
    			<HeaderText>
    				<Qualifier>PUR</Qualifier>
    				<Text>Test1:</Text>
    			</HeaderText>
    			<HeaderText>
    				<Qualifier>PUR</Qualifier>
    				<Text>Test2</Text>
    			</HeaderText>			
    			<LineItem>
    				<Line>1</Line>			
                <LineText>
    				<Qualifier>PUR</Qualifier>
    				<Text>Test3</Text>
    			</LineText>
                <LineText>
        			<Qualifier>PUR</Qualifier>
    				<Text>Test4</Text>
    			</LineText>			
    			</LineItem>
    		</HeaderInformation>
    	</Interchange>
    </SALESORDER>
    

    XSLT:

    <?xml version="1.0" encoding="utf-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
        <xsl:output method="xml" indent="yes"/>
    
    
    
    <xsl:key name="qualifierKey" match="HeaderText" use="Qualifier" />
    <xsl:key name="qualifierTextKey" match="HeaderText" use="concat(Qualifier, '|', Text)" />
    
    <xsl:key name="qualifierKey" match="LineText" use="Qualifier" />
    <xsl:key name="qualifierTextKey" match="LineText" use="concat(Qualifier, '|', Text)" />
    
        <xsl:template match="@* | node()">
            <xsl:copy>
                <xsl:apply-templates select="@* | node()"/>
            </xsl:copy>
        </xsl:template>
        
    <xsl:template match="HeaderText[position() &gt; 1]" />
    <xsl:template match="LineText[position() &gt; 1]" />
    
    <!-- HeaderText zusammenführe, falls derselbe Qualifier mehrmals gesendet wird -->
    <xsl:template match="HeaderText[following-sibling::*[1]][generate-id() = generate-id(key('qualifierKey',Qualifier)[1])]">
        <HeaderText>
        <!-- Add LineNum with counter to HeaderText, so we can input all TextAllocations -->
                <LineNum>
                <xsl:number/>
            </LineNum> 
            <Qualifier>
                <xsl:value-of select="normalize-space(Qualifier)" />
            </Qualifier>
            <Text>
                <xsl:variable name="count" select="count(key('qualifierKey',Qualifier)[generate-id() = generate-id(key('qualifierTextKey', concat(Qualifier, '|', Text))[1])])" />
                <xsl:for-each select="key('qualifierKey',Qualifier)[generate-id() = generate-id(key('qualifierTextKey', concat(Qualifier, '|', Text))[1])]">
    
                    <xsl:value-of select="normalize-space(Text)" />
                    <xsl:if test="$count != position()"><xsl:value-of select="' '"></xsl:value-of></xsl:if>
                </xsl:for-each>
            </Text>
        </HeaderText>
    </xsl:template>
    
    <!-- LineText zusammenführe, falls derselbe Qualifier mehrmals gesendet wird -->
    <xsl:template match="LineText[following-sibling::*[1]][generate-id() = generate-id(key('qualifierKey',Qualifier)[1])]">
        <LineText>
        <!-- Add LineNum with counter to HeaderText, so we can input all TextAllocations -->
                <LineNum>
                <xsl:number/>
            </LineNum> 
            <Qualifier>
                <xsl:value-of select="normalize-space(Qualifier)" />
            </Qualifier>
            <Text>
                <xsl:variable name="count" select="count(key('qualifierKey',Qualifier)[generate-id() = generate-id(key('qualifierTextKey', concat(Qualifier, '|', Text))[1])])" />
                <xsl:for-each select="key('qualifierKey',Qualifier)[generate-id() = generate-id(key('qualifierTextKey', concat(Qualifier, '|', Text))[1])]">
    
                    <xsl:value-of select="normalize-space(Text)" />
                    <xsl:if test="$count != position()"><xsl:value-of select="' '"></xsl:value-of></xsl:if>
                </xsl:for-each>
            </Text>
        </LineText>
    </xsl:template>
    
    </xsl:stylesheet>
    
    1. Hallo Julian,

      war gerade am ersten XML-Code dran, als Du wieder mal die Perspektive gewechselt hast.

      Probiere es 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="header_text" match="HeaderText" use="Qualifier"/>
        <xsl:key name="line_text" match="LineText" use="Qualifier"/>
      
        <xsl:template match="@* | node()">
          <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
          </xsl:copy>
        </xsl:template>
      
        <xsl:template match="HeaderText">
          <xsl:for-each select=".[generate-id() = generate-id(key('header_text', Qualifier)[1])]">
            <HeaderText>
              <xsl:copy-of select="Qualifier"/>
              <Text>
                <xsl:for-each select="key('header_text', Qualifier)">
                  <xsl:value-of select="Text"/>
                  <xsl:if test="position() != last()">
                    <xsl:text> </xsl:text>
                  </xsl:if>
                </xsl:for-each>
              </Text>
            </HeaderText>
          </xsl:for-each>
        </xsl:template>
      
        <xsl:template match="LineText">
          <xsl:for-each select=".[generate-id() = generate-id(key('line_text', Qualifier)[1])]">
            <LineText>
              <xsl:copy-of select="Qualifier"/>
              <Text>
                <xsl:for-each select="key('line_text', Qualifier)">
                  <xsl:value-of select="Text"/>
                  <xsl:if test="position() != last()">
                    <xsl:text> </xsl:text>
                  </xsl:if>
                </xsl:for-each>
              </Text>
            </LineText>
          </xsl:for-each>
        </xsl:template>
      
      </xsl:stylesheet>
      

      Grüße,
      Thomas

      1. danke, wollte es gerade ausbessern. Hatte aber auf einmal keine Berechtigung mehr und mein neuer Eintrag wurde gelöscht??

        Aber danke vielmals!