Announcement

Collapse
No announcement yet.

xml nach csv

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • xml nach csv

    Hallo,

    habe eine große Bitte:

    wird dieses Stylesheet
    Code:
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text"/>
    
    
    <xsl:template name="delim">
      <xsl:text>;</xsl:text>
    </xsl:template>
    
    
    <xsl:template match="/">
    	<xsl:apply-templates />
    </xsl:template>
    
    <xsl:template match="H/L">
     <xsl:for-each select="@*[position() &gt; 0]">
    
    		<xsl:value-of select="."/>
    
    		<xsl:if test="position() != last()">
    			<xsl:call-template name="delim"/>
    		</xsl:if>
    
     </xsl:for-each>
    
     <!-- neue Zeile '
    ' -->
     <xsl:text>
    </xsl:text> 
    </xsl:template>
    
    <xsl:template match="M/L">
     <xsl:choose>
      <xsl:when test="@b" >
       <xsl:for-each select="@*">
    		<xsl:value-of select="."/>
    		<xsl:if test="position() != last()">
    			<xsl:call-template name="delim"/>
    		</xsl:if>
       </xsl:for-each>
      </xsl:when>
     <xsl:otherwise>
    
       <xsl:for-each select="@*">
    	<xsl:choose>
    	  <xsl:when test="position() != 2"> 
    		<xsl:value-of select="."/>
    		<xsl:if test="position() != last()">
    			<xsl:call-template name="delim"/>
    		</xsl:if>
    	  </xsl:when>
    	  <xsl:otherwise> 
    		<xsl:call-template name="delim"/>
    		<xsl:value-of select="."/>
    		<xsl:if test="position() != last()">
    			<xsl:call-template name="delim"/>
    		</xsl:if>
    	  </xsl:otherwise>
    	</xsl:choose>
       </xsl:for-each>
    
     </xsl:otherwise>
     </xsl:choose>
    
     <!-- neue Zeile '
    ' -->
     <xsl:text>
    </xsl:text> 
    </xsl:template>
    
    
    </xsl:stylesheet>
    auf dieses XML (Auszug) angewendet
    Code:
    <?xml version="1.0" encoding="iso-8859-1"?>
    <C>
      <H>
         <L a="10" b="Dummy1"/>
      </H>
    
      <M>
         <L a="61" b="1Dummy2-"/>
         <L a="62" b="2Dummy2" c="S001" d="F"/>
         <L a="62"  c="S002" d="F"/>
      </M>
    
      <H>
         <L a="51" b="1Dummy3"/>
         <L a="52" b="2Dummy3"/>
      </H>
    
      <M>
         <L a="62" b="Dummy4" c="S003" d="G"/>
         <L a="62"  c="S004" d="H"/>
         <L a="62"  c="S005" d="I"/>
      </M>
    
      <M>
         <L a="62" b="Dummy5" c="S007" d="X"/>
         <L a="62"  c="S007" d="Y"/>
         <L a="62"  c="S007" d="Z"/>
      </M>
    </C>
    erhalte ich folgende Ausgabe:
    Code:
    10;Dummy1
    61;1Dummy2-
    62;2Dummy2;S001;F
    62;;S002;F
    51;1Dummy3
    52;2Dummy3
    62;Dummy4;S003;G
    62;;S004;H
    62;;S005;I
    62;Dummy5;S007;X
    62;;S007;Y
    62;;S007;Z
    Schön wäre eine Lösung, die diese Ausgabe erzeugt:
    Code:
    10;Dummy1
    62;1Dummy22Dummy2;S001;F
    62;1Dummy22Dummy2;S002;F
    52;1Dummy3*2Dummy3
    62;Dummy4;S003;G
    62;Dummy4;S004;H
    62;Dummy4;S005;I
    62;Dummy5;S007;X
    62;Dummy5;S007;Y
    62;Dummy5;S007;Z
    Meine Versuche beispielsweise die Werte der b-Attribute zu verketten sehen so aus:
    Code:
    <xsl:template match="H">
    	<xsl:variable name="L-zusammen">
      		<xsl:for-each select="L/@b">
        			<xsl:value-of select="."/>
    			
    			<xsl:if test="position() !=last()">
    				<xsl:text>&#160;</xsl:text>
    			</xsl:if>
    
      		</xsl:for-each>
    	</xsl:variable>
    	<xsl:copy-of select="$L-zusammen"/>
    </xsl:template>
    Die gewünschte Ausgabe bekomme ich aber einfach nicht hin. Wie geht man so etwas an? Kann mir bitte jemand helfen?
    Die Transformation erfolgt mit MSXML und VB(A) in Anlehnung an
    http:////www.sbslimited.co.uk/xmltocsv.html

    Danke und Gruß
    MaxW

  • #2
    Versuche mal mit Worten zu erklären, wie Eingabe
    Code:
    <C>
      <H>
         <L a="10" b="Dummy1"/>
      </H>
    
      <M>
         <L a="61" b="1Dummy2-"/>
         <L a="62" b="2Dummy2" c="S001" d="F"/>
         <L a="62"  c="S002" d="F"/>
      </M>
    
      <H>
         <L a="51" b="1Dummy3"/>
         <L a="52" b="2Dummy3"/>
      </H>
    
      <M>
         <L a="62" b="Dummy4" c="S003" d="G"/>
         <L a="62"  c="S004" d="H"/>
         <L a="62"  c="S005" d="I"/>
      </M>
    
      <M>
         <L a="62" b="Dummy5" c="S007" d="X"/>
         <L a="62"  c="S007" d="Y"/>
         <L a="62"  c="S007" d="Z"/>
      </M>
    </C>
    und Resultat
    Code:
    10;Dummy1
    62;1Dummy22Dummy2;S001;F
    62;1Dummy22Dummy2;S002;F
    52;1Dummy3*2Dummy3
    62;Dummy4;S003;G
    62;Dummy4;S004;H
    62;Dummy4;S005;I
    62;Dummy5;S007;X
    62;Dummy5;S007;Y
    62;Dummy5;S007;Z
    zusammenhängen, insbesondere welche Elemente bzw. Attribute nicht ausgegeben werden sollen und welche konkateniert werden sollen.

    Comment


    • #3
      Die Eingabe ist als Tabelle zu verstehen:
      L-Elemente sind die Zeilen, deren Attributnamen (a,b,c, ...) die Spalten.

      L-Kindelemente von H haben hier immer nur zwei Attribute (=Spalten).
      Mehrere L-Kindelemente entsprechen mehrzeiligem Inhalt(sog. Folgezeilen) und sollen in der Ausgabe zusammengefasst werden, wobei der Wert des a-Attributs, des letzten L-Kindelements vorangestellt werden soll.

      Eingabe zweites H-Element:

      <H>
      <L a="51" b="1Dummy3"/>
      <L a="52" b="2Dummy3"/>
      </H>

      Ausgabe:

      52;1Dummy3 2Dummy3


      Bei den L-Kindelementen von M verhält es sich mit den Folgezeilen genauso.
      Werte der b-Attribute sollen für die Ausgabe zusammengefasst werden und
      in der Ausgabe wiederholt werden, sollte ein L-Element kein b-Attribut haben

      Eingabe: erstes M-Element:

      <M>
      <L a="61" b="1Dummy2-"/>
      <L a="62" b="2Dummy2" c="S001" d="F"/>
      <L a="62" c="S002" d="F"/>
      </M>

      Ausgabe

      62;1Dummy22Dummy2;S001;F
      62;1Dummy22Dummy2;S001;F


      Eingabe: zweites M-Element:

      <M>
      <L a="62" b="Dummy4" c="S003" d="G"/>
      <L a="62" c="S004" d="H"/>
      <L a="62" c="S005" d="I"/>
      </M>

      Ausgabe

      62;Dummy4;S003;G
      62;Dummy4;S004;H
      62;Dummy4;S005;I
      Zuletzt editiert von MaxW; 15.04.2012, 10:35.

      Comment


      • #4
        Für H/L habe ich folgendes geschrieben:
        Code:
        <xsl:stylesheet 
          version="1.0"
          xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
          
        <xsl:param name="lf" select="'&#xA;'"/>
        <xsl:param name="sep" select="';'"/>
        <xsl:param name="hsep" select="' '"/>
        <xsl:param name="msep" select="''"/>
        
        <xsl:output method="text"/>
        <xsl:strip-space elements="*"/>
        
        <xsl:template match="H/L[position() &lt; last()]"/>
        
        <xsl:template match="H/L[last()]">
          <xsl:value-of select="@a"/>
          <xsl:value-of select="$sep"/>
          <xsl:apply-templates select="../L/@b"/>
          <xsl:value-of select="$lf"/>
        </xsl:template>
        
        <xsl:template match="H/L/@b">
          <xsl:if test="position() > 1">
            <xsl:value-of select="$hsep"/>
          </xsl:if>
          <xsl:value-of select="."/>
        </xsl:template>
        
        
        </xsl:stylesheet>
        Für M/L habe ich noch nicht verstanden, warum das Element
        Code:
        <L a="61" b="1Dummy2-"/>
        nicht in einer Zeile resultiert bzw. wann L-Elemente zusammenfasst werden und wann nicht.

        Comment


        • #5
          Sorry, die Erklärung für M/L ist mir nicht gelungen, zumal in der
          Darstellung der gewünschten Ausgabe für das erste M-Element mir
          leider ein Fehler unterlaufen ist:

          Erneuter Versuch:

          Beispiel: erstes M-Element:

          <M>
          <L a="61" b="1Dummy2-"/>
          <L a="62" b="2Dummy2" c="S001" d="F"/>
          <L a="62" c="S002" d="F"/>
          </M>

          richtige Ausgabe für erstes M-Elemt

          62;1Dummy22Dummy2;S001;F
          62;1Dummy22Dummy2;S002;F


          Das bedeutet, Werte der b-Attribute werden immer zusammengefasst.
          Bei L-Elementen ohne c und d Attribut in der Eingabe,
          handelt es sich um "Vorgängerzeilen (aufgeteilte Texte),
          die in der Ausgabe zusammengefasst werden sollen.


          Folgt ein L-Element mit c und d Attribut, aber ohne b-Attribut,
          soll in der Ausgabe die "zusammengesetzte Zeichenkette wiederholt werden.
          Deswegen hier im Beispiel 2 Zeilen aus drei L-Elementen.

          Schön wäre, so der Wert des b-Attributs mit "-" endet, dieser
          vor dem Zusammenfügen entfernt würde...


          Im Beispiel zum zweiten M-Element

          <M>
          <L a="62" b="Dummy4" c="S003" d="G"/>
          <L a="62" c="S004" d="H"/>
          <L a="62" c="S005" d="I"/>
          </M>

          soll der Wert des b-Attributs für nachfolgende L-Elemente wiederholt
          werden, so dass hier folgende drei Zeilen ausgegeben werden

          62;Dummy4;S003;G
          62;Dummy4;S004;H
          62;Dummy4;S005;I

          Comment


          • #6
            Hier ein Beispiel:
            Code:
            <xsl:stylesheet 
              version="1.0"
              xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
              
            <xsl:param name="lf" select="'&#xA;'"/>
            <xsl:param name="sep" select="';'"/>
            <xsl:param name="hsep" select="'*'"/>
            <xsl:param name="msep" select="''"/>
            
            <xsl:output method="text"/>
            <xsl:strip-space elements="*"/>
            
            <xsl:template match="M/L[not(@c) and not(@d)]"/>
            
            <xsl:template match="M/L[@c and @d]">
              <xsl:value-of select="@a"/>
              <xsl:value-of select="$sep"/>
              <xsl:apply-templates select="preceding-sibling::L/@b | @b"/>
              <xsl:value-of select="$sep"/>
              <xsl:apply-templates select="@c | @d"/>
              <xsl:value-of select="$lf"/>
            </xsl:template>
            
            <xsl:template match="M/L/@b">
              <xsl:choose>
                <xsl:when test="position() != last()">
                  <xsl:value-of select="concat(substring(., 1, string-length(.) - 1), 
                                               translate(substring(., string-length(.)), '-', ''))"/>
                </xsl:when>
                <xsl:otherwise>
                  <xsl:value-of select="."/>
                </xsl:otherwise>
              </xsl:choose>
              <xsl:value-of select="$msep"/>
            </xsl:template>
            
            <xsl:template match="M/L/@c | M/L/@d">
              <xsl:if test="position() > 1">
                <xsl:value-of select="$sep"/>
              </xsl:if>
              <xsl:value-of select="."/>
            </xsl:template>
            
            <xsl:template match="H/L[position() &lt; last()]"/>
            
            <xsl:template match="H/L[last()]">
              <xsl:value-of select="@a"/>
              <xsl:value-of select="$sep"/>
              <xsl:apply-templates select="../L/@b"/>
              <xsl:value-of select="$lf"/>
            </xsl:template>
            
            <xsl:template match="H/L/@b">
              <xsl:if test="position() > 1">
                <xsl:value-of select="$hsep"/>
              </xsl:if>
              <xsl:value-of select="."/>
            </xsl:template>
            
            
            </xsl:stylesheet>
            Damit macht Saxon 6.5.5 aus
            Code:
            <C>
              <H>
                 <L a="10" b="Dummy1"/>
              </H>
            
              <M>
                 <L a="61" b="1Dummy2-"/>
                 <L a="62" b="2Dummy2" c="S001" d="F"/>
                 <L a="62"  c="S002" d="F"/>
              </M>
            
              <H>
                 <L a="51" b="1Dummy3"/>
                 <L a="52" b="2Dummy3"/>
              </H>
            
              <M>
                 <L a="62" b="Dummy4" c="S003" d="G"/>
                 <L a="62"  c="S004" d="H"/>
                 <L a="62"  c="S005" d="I"/>
              </M>
            
              <M>
                 <L a="62" b="Dummy5" c="S007" d="X"/>
                 <L a="62"  c="S007" d="Y"/>
                 <L a="62"  c="S007" d="Z"/>
              </M>
            </C>
            das Resultat
            Code:
            10;Dummy1
            62;1Dummy22Dummy2;S001;F
            62;1Dummy22Dummy2;S002;F
            52;1Dummy3*2Dummy3
            62;Dummy4;S003;G
            62;Dummy4;S004;H
            62;Dummy4;S005;I
            62;Dummy5;S007;X
            62;Dummy5;S007;Y
            62;Dummy5;S007;Z

            Comment


            • #7
              Hallo Martin,

              vielen herzlichen Dank!

              Gruß, MaxW

              Comment

              Working...
              X