Announcement

Collapse
No announcement yet.

Transformation nach Bulleted List

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

  • Transformation nach Bulleted List

    Als Beispiel diese XML Daten:

    Code:
    <?xml version="1.0" encoding="utf-8"?>
    <fragmentRoot>
      <html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns="http://www.w3.org/TR/REC-html40">
        <body lang="DE-AT" style="tab-interval:35.4pt">
          <!--StartFragment-->
          <p class="Table8pBullet">
            <strong>Elektrischer Schutz</strong>
          </p>
          <p class="Table8pBullet2">Überstrom/Unterstrominkl. der schnellenStromfunktionen (64REF, 50BF, I>>>, U>>> (Trigger auf Momentanwerte)</p>
          <p class="Table8pBullet2">Über-/Unterspannungsschutz</p>
          <p class="Table8pBullet2">Ständererdschlussschutz</p>
          <p class="Table8pBullet2">Untererregungsschutz</p>
          <p class="Table8pBullet2">
            <span style="background:yellow;mso-highlight:yellow">Differentialschutz</span>
          </p>
          <p class="Table8pBullet2">Überstromschutz gerichtet</p>
          <p class="Table8pBullet2">Überstromschutz IDMT</p>
          <p class="Table8pBullet"><strong>Erregung</strong></p>
          <p class="Table8pBullet2">Generator-Spannungsregelung</p>
          <p class="Table8pBullet2">Feldstromregler</p>
          <!--EndFragment-->
        </body>
      </html>
    </fragmentRoot>
    Enstehen soll etwa dieses, als (x)HTML:
    • Elektrischer Schutz
      • Überstrom/Unterstrominkl. der schnellenStromfunktionen (64REF, 50BF, I&gt;&gt;&gt;, U&gt;&gt;&gt; (Trigger auf Momentanwerte)
      • Über-/Unterspannungsschutz
      • Ständererdschlussschutz
      • Untererregungsschutz
      • Differentialschutz
      • Überstromschutz gerichtet
      • Überstromschutz IDMT
    • Erregung
      • Generator-Spannungsregelung
      • Feldstromregler


    Es gibt maximal 3 Ebenen, erkenntlich an:
    • Table8pBullet
    • Table8pBullet 2
    • Table8pBullet 3

    Statt der Zeichen (Differentialschutz) sollte der Background entsprechend farblich gesetzt sein, wie im XML ersichtlich.

    Das wird mittels XSLT zu lösen sein.

    Ich werd mich mal daran veresuchen ... Hilfe wird sehr gerne angenommen!!
    Gruß,
    georgie

  • #2
    Versuche es mit folgendem Ansatz:
    Code:
    <xsl:stylesheet
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:html4="http://www.w3.org/TR/REC-html40"
      xmlns="http://www.w3.org/1999/xhtml"
      exclude-result-prefixes="html4"
      version="1.0">
      
      <xsl:output method="xml" indent="yes"/>
      
      <xsl:key name="k1" 
        match="html4:body/html4:p[@class = 'Table8pBullet2' or @class = 'Table8pBullet3']"
        use="generate-id(preceding-sibling::html4:p[@class = 'Table8pBullet'][1])"/>
        
      <xsl:key name="k2"
        match="html4:body/html4:p[@class = 'Table8pBullet3']"
        use="generate-id(preceding-sibling::html4:p[@class = 'Table8pBullet2'][1])"/>
        
      <xsl:template match="@*">
        <xsl:copy/>
      </xsl:template>
      
      <xsl:template match="html4:*">
        <xsl:element name="{local-name()}">
          <xsl:apply-templates select="@* | node()"/>
        </xsl:element>
      </xsl:template>
      
      <xsl:template match="html4:body">
        <xsl:element name="{local-name()}">
          <xsl:apply-templates select="@*"/>
          <xsl:variable name="list" select="html4:p[@class = 'Table8pBullet']"/>
          <xsl:if test="$list">
            <ul>
              <xsl:apply-templates select="$list" mode="list"/>
            </ul>
          </xsl:if>
        </xsl:element>
      </xsl:template>
      
      <xsl:template match="html4:body/html4:p[@class = 'Table8pBullet']" mode="list">
        <li>
          <xsl:apply-templates/>
          <xsl:variable name="group" select="key('k1', generate-id())"/>
          <xsl:if test="$group">
            <ul>
              <xsl:apply-templates select="$group[self::html4:p[@class = 'Table8pBullet2']]" mode="list"/>
            </ul>
          </xsl:if>
        </li>
      </xsl:template>
      
      <xsl:template match="html4:body/html4:p[@class = 'Table8pBullet2']" mode="list">
        <li>
          <xsl:apply-templates/>
          <xsl:variable name="group" select="key('k2', generate-id())"/>
          <xsl:if test="$group">
            <ul>
              <xsl:apply-templates select="$group"/>
            </ul>
          </xsl:if>
        </li>
      </xsl:template>
      
      <xsl:template match="html4:body/html4:p[@class = 'Table8pBullet3']">
        <li>
          <xsl:apply-templates/>
        </li>
      </xsl:template>
      
    </xsl:stylesheet>
    Ich habe das aber nur mit deinem geposteten Beispiel getestet und das enthaelt keine "Table8pBullet3"-Ebene, der Teil ist also nicht getestet.

    Comment


    • #3
      Besten Dank!!!

      Dass das Stylesheet so kompliziert und aufwändig wird, hatte ich gar nicht vermutet. Es hat dich sicher auch eine Menge Zeit gekostet!

      Ich mache mich morgen gleich daran, es auch mit Ebene 3 zu testen. Und vor allem mit den eigentlichen Dokumentfragmenten.

      Vor Zeiten habe ich, damals noch in VB6, die Transformation direkt im Programm und am XmlDocument durchgeführt, sogar mehrere Transformationen hinter einander, wenn das notwendig war. Die Stylesheets dazu lagen im File System (*.xsl).

      Ich will das in VB.NET immer noch so machen (mit eben nur einer Transformation). Ich habe oXMLDOMNode.transformNode (objStylesheet) gefunden (MSXML 4.0 SDK). Mal schaun was das hergibt in VS 2003 ... weil mit IntelliSense finde ich's noch nicht.
      Zuletzt editiert von georgie; 15.02.2011, 23:27.
      Gruß,
      georgie

      Comment


      • #4
        Wenn du VB.NET und XSLT benutzen willst, dann mittels System.Xml.XslCompiledTransform (in .NET 2.0 oder neuer) bzw. mittels System.Xml.XslTransform (in .NET 1.x).

        Comment


        • #5
          Das Stylesheet funktioniert auch mit Ebene 3 exzellent :-))

          Vielen Dank dafür!
          Gruß,
          georgie

          Comment


          • #6
            Originally posted by georgie View Post
            Das Stylesheet funktioniert auch mit Ebene 3 exzellent :-))!
            Das stimmt nach wie vor.

            Aber ich habe in den XML Daten vergessen, <p> nodes einzufügen, die keine Auszeichnung als "bulleted" haben (entspricht "normalem" Text). Diese werden zur Zeit vom Stylesheet nicht kopiert.

            Neue XML Daten:

            Code:
            <?xml version="1.0" encoding="utf-8"?>
            <fragmentRoot>
              <html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns="http://www.w3.org/TR/REC-html40">
                <body lang="DE-AT" style="tab-interval:35.4pt">
                  <!--StartFragment-->
                  <p class="irgendein style">Dieser Text muss im Ergebnis auch aufscheinen!</p>
                  <p class="irgendein style">Dieser Text muss im Ergebnis auch aufscheinen!</p>
                  <p class="Table8pBullet">
                    <strong>Elektrischer Schutz</strong>
                  </p>
                  <p class="Table8pBullet2">Überstrom/Unterstrominkl. der schnellenStromfunktionen (64REF, 50BF, I>>>, U>>> (Trigger auf Momentanwerte)</p>
                  <p class="Table8pBullet2">Über-/Unterspannungsschutz</p>
                  <p class="Table8pBullet3">Ständererdschlussschutz</p>
                  <p class="Table8pBullet3">Untererregungsschutz</p>
                  <p class="Table8pBullet2">
                    <span style="background:yellow;mso-highlight:yellow">Differentialschutz</span>
                  </p>
                  <p class="Table8pBullet2">Überstromschutz gerichtet</p>
                  <p class="Table8pBullet2">Überstromschutz IDMT</p>
                  <p class="Table8pBullet"><strong>Erregung</strong></p>
                  <p class="Table8pBullet2">Generator-Spannungsregelung</p>
                  <p class="Table8pBullet2">Feldstromregler</p>
                  <p class="irgendein style">Dieser Text muss im Ergebnis auch aufscheinen!</p>
                  <p class="irgendein style">Dieser Text muss im Ergebnis auch aufscheinen!</p>
                  <!--EndFragment-->
                </body>
              </html>
            </fragmentRoot>
            Ich habe class="irgendein style" geschrieben um anzudeuten, dass es sich um andere Werte für class handelt als jene, die explizit abgefragt werden.

            Lieber Martin, könntest du bitte diese Änderung berücksichtigen? Mir ist das Stylesheet zu kompliziert, um es selber zu versuchen ...

            Danke im voraus!
            Zuletzt editiert von georgie; 17.02.2011, 03:05.
            Gruß,
            georgie

            Comment


            • #7
              Ich habe das Stylesheet den neuen Anforderungen angepasst:
              Code:
              <xsl:stylesheet
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:html4="http://www.w3.org/TR/REC-html40"
                xmlns="http://www.w3.org/1999/xhtml"
                exclude-result-prefixes="html4"
                version="1.0">
                
                <xsl:output method="xml" indent="yes"/>
                
                <xsl:key name="k1" 
                  match="html4:body/html4:p[@class = 'Table8pBullet2' or @class = 'Table8pBullet3']"
                  use="generate-id(preceding-sibling::html4:p[@class = 'Table8pBullet'][1])"/>
                  
                <xsl:key name="k2"
                  match="html4:body/html4:p[@class = 'Table8pBullet3']"
                  use="generate-id(preceding-sibling::html4:p[@class = 'Table8pBullet2'][1])"/>
                  
                <xsl:key name="k3"
                  match="html4:body/html4:p[@class = 'Table8pBullet' or @class = 'Table8pBullet2' or @class = 'Table8pBullet3']
                          [preceding-sibling::html4:p[@class = 'Table8pBullet' or @class = 'Table8pBullet2' or @class = 'Table8pBullet3'][1]]"
                  use="generate-id(preceding-sibling::html4:p[@class = 'Table8pBullet']
                         [not(preceding-sibling::*[1][@class = 'Table8pBullet' or @class = 'Table8pBullet2' or @class = 'Table8pBullet3'])])"/>
                  
                <xsl:template match="@*">
                  <xsl:copy/>
                </xsl:template>
                
                <xsl:template match="html4:*">
                  <xsl:element name="{local-name()}">
                    <xsl:apply-templates select="@* | node()"/>
                  </xsl:element>
                </xsl:template>
                
                <xsl:template match="html4:body">
                  <xsl:element name="{local-name()}">
                    <xsl:apply-templates select="@* | *"/>
                  </xsl:element>
                </xsl:template>
                
                <xsl:template match="html4:body/html4:p[@class = 'Table8pBullet' or @class = 'Table8pBullet2' or @class = 'Table8pBullet3']
                  [preceding-sibling::*[1][self::html4:p[@class = 'Table8pBullet' or @class = 'Table8pBullet2' or @class = 'Table8pBullet3']]]"/>
                
                <xsl:template match="html4:body/html4:p[@class = 'Table8pBullet']
                  [not(preceding-sibling::*[1][@class = 'Table8pBullet' or @class = 'Table8pBullet2' or @class = 'Table8pBullet3'])]">
                  <ul>
                    <xsl:apply-templates select=". | key('k3', generate-id())[self::html4:p[@class = 'Table8pBullet']]" mode="list"/>
                  </ul>
                </xsl:template>
                
                <xsl:template match="html4:body/html4:p[@class = 'Table8pBullet']" mode="list">
                  <li>
                    <xsl:apply-templates/>
                    <xsl:variable name="group" select="key('k1', generate-id())"/>
                    <xsl:if test="$group">
                      <ul>
                        <xsl:apply-templates select="$group[self::html4:p[@class = 'Table8pBullet2']]" mode="list"/>
                      </ul>
                    </xsl:if>
                  </li>
                </xsl:template>
                
                <xsl:template match="html4:body/html4:p[@class = 'Table8pBullet2']" mode="list">
                  <li>
                    <xsl:apply-templates/>
                    <xsl:variable name="group" select="key('k2', generate-id())"/>
                    <xsl:if test="$group">
                      <ul>
                        <xsl:apply-templates select="$group" mode="list"/>
                      </ul>
                    </xsl:if>
                  </li>
                </xsl:template>
                
                <xsl:template match="html4:body/html4:p[@class = 'Table8pBullet3']" mode="list">
                  <li>
                    <xsl:apply-templates/>
                  </li>
                </xsl:template>
                
              </xsl:stylesheet>
              Derart komplexe Dinge sollte man aber besser mit XSLT 2.0 und for-each-group group-adjacent/group-starting-with machen, da wird der Code kuerzer und bleibt lesbar.

              Comment


              • #8
                Ab heute habe ich, weil ich mich beklagt habe, VS 2010 zur Verfügung.
                Ich muss nur mehr in die Firma fahren und es installieren :-)
                Vielleicht heute noch ...

                Mit .NET 4.0 sollte XSLT 2.0 ja wohl kein Problem mehr sein, oder?

                Es tut mir echt Leid, wenn ich den Aufwand unsinnig in die Höhe getrieben habe. Es hat halt ein bisserl gedauert, bis VS 2010 gelandet ist.
                Gruß,
                georgie

                Comment


                • #9
                  Microsoft selbst bietet leider auch in .NET 4.0 keine XSLT 2.0 Unterstützung, aber es gibt diverse Angebote anderer Parteien, wie Saxon 9 (http://saxon.sourceforge.net/), AltovaXML Tools (http://www.altova.com/altovaxml.html) und XQSharp (http://www.xqsharp.com/).

                  Comment


                  • #10
                    AFAIK kann .NET aus eigener Kraft noch immer nur 1.0, aber XQSharp kann helfen (funktioniert zumindest in der Standalone-EXE-Version problemlos mit 2.0-Stylesheets, erfolgreich getestet mit diesem Projekt).

                    Comment


                    • #11
                      Hallo Martin,

                      ich sehe dass du gerade eben online bist.

                      Die Anforderungen an die Template, die du erzeugt hattest, wurden ein bisschen erweitert. Ich habe dir deswegen eine private Nachricht im Forum geschrieben. Ich möchte gerne mit dir in direkten Kontakt treten.

                      Grüße
                      georgie
                      Gruß,
                      georgie

                      Comment

                      Working...
                      X