Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   XML (https://www.delphipraxis.net/46-xml/)
-   -   Delphi XML / XSLT Reihenfolge definieren. (https://www.delphipraxis.net/81677-xml-xslt-reihenfolge-definieren.html)

StTüff 1. Dez 2006 12:39


XML / XSLT Reihenfolge definieren.
 
Hallo!

Ich habe ein recht einfaches Problem, an dem ich aber beinahe verzweifle. Ich verfolge vermutlich den falschen Ansatz. Vielleicht kann mich jemand auf die richtige Bahn lenken.

Ich habe eine XML-Datei mit folgender Struktur:
XML-Code:
<ebeneA att1="1">
  <ebeneB2 att4="1">
    <ebeneD att5="1"/>
  </ebeneB2>
  <ebeneB1 att2="1">
    <ebeneC att3="1"/>
  </ebeneB1>
</ebeneA>
Ich möchte nun mittels XSL die Struktur so verändern, dass "ebeneB2" mit "ebeneB1" schlicht und einfach getauscht wird. Also in diese Form:
XML-Code:
<ebeneA att1="1">
  <ebeneB1 att2="1">
    <ebeneC att3="1"/>
  </ebeneB1>
  <ebeneB2 att4="1">
    <ebeneD att5="1"/>
  </ebeneB2>
</ebeneA>
Ich habe nun versucht das so zu lösen:
XML-Code:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/ | @* | node()">
   



    <xsl:apply-templates select="ebeneA | @* | node()"/>
    <xsl:apply-templates select="ebeneA/ebeneB1 | @* | node()"/>
    <xsl:apply-templates select="ebeneA/ebeneB2 | @* | node()"/>
   </p>
  </xsl:template>

  <xsl:template match="ebeneB1 | @* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>
  <xsl:template match="ebeneB2 | @* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>
  <xsl:template match="ebeneA | @* | node()">
    <xsl:copy>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>
Dabei kommt dann aber natürlich folgendes raus:
XML-Code:
<?xml version="1.0"?>




  <ebeneA/>
  <ebeneA/>
  <ebeneB1 att2="1">
    <ebeneC/>
  </ebeneB1>
  <ebeneA/>
  <ebeneB2 att4="1">
    <ebeneD/>
  </ebeneB2>
</p>
Ich habe diverse Varianten versucht, konnte aber den "Durchbruch" noch nicht schaffen. :wall:

Vermutlich ist die Lösung recht einfach. Um so dankbarer bin ich, wenn mir einer auf die Sprünge helfen könnte. Ich bin auf diesem Gebiet noch absoluter Neuling.

Gruß und schon mal vielen Dank,

StTüff

[edit=Christian Seehase]Editiert, damit der Code wieder angezeigt wird. Mfg, Christian Seehase[/edit]

marabu 1. Dez 2006 14:57

Re: XML / XSLT Reihenfolge definieren.
 
Hallo,

im konkreten Fall deines Beispieldokuments reicht das hier:

XML-Code:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
  <xsl:template match="/ | @* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()">
        <xsl:sort select="local-name()"/>
      </xsl:apply-templates>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>
Sollte dein echtes Dokument allerdings einen anderen Aufbau haben, dann musst du mal das Schema zeigen oder den Aufbau hinreichend genau beschreiben.

Grüße vom marabu

[edit=Christian Seehase]Editiert, damit der Code wieder angezeigt wird. Mfg, Christian Seehase[/edit]

StTüff 2. Dez 2006 10:11

Re: XML / XSLT Reihenfolge definieren.
 
Hallo marabu!

Erst mal vielen Dank für die Antwort! :-D
Das sortieren funktioniert natürlich nur bei dem Beispiel, weil für die Knotennamen eine Bezeichnung gewählt wurde, die (zufällig) eine Sortierung zulässt. Ich gebe zu das mein Beispiel in sofern schlecht war.

Das eigentliche Zeil, das ich erreichen wollte ist, über die Transformation eine vorgegebene Reihenfolge zu erhalten.
Um das noch mal klarer zu machen, möchte ich das Beispiel um "ebeneB3" erweitern.

Ich möchte dann über die xsl-transformation z.B. folgende Reihenfolge festlegen können:
XML-Code:
<ebeneA att1="1">
  <ebeneB1 att2="1">
    <ebeneC att3="1"/>
  </ebeneB1>
  <ebeneB3 att4="1">
    <ebeneD att5="1"/>
  </ebeneB3>
  <ebeneB2 att4="1">
    <ebeneD att5="1"/>
  </ebeneB2>
</ebeneA>
Das geht dann mit Sortieren nicht mehr. Natürlich könnte man nun sagen: "Dann sorg doch dafür, dass es von vornherein richtig im XML-File steht". Das ist aber leider nicht möglich.

Da ich aber die Knotennamen kenne, bin ich auf die Idee gekommen, dies durch Filtern und gezieltes Zusammensetzen zu realisieren (das war die ursprüngliche Idee).
Vielleicht gibt es ja noch die Möglichkeit einer "Sortiervorlage" o.Ä. über die ich beim Wälzen der Dokumentation noch nicht gestolpert bin. Ich habe das gefühl, dass es ein ganz einfach Lösung geben wird, die ich (noch) nicht gefunden habe :gruebel:

Gruß,

StTüff

[edit=Christian Seehase]Editiert, damit der Code wieder angezeigt wird. Mfg, Christian Seehase[/edit]

marabu 2. Dez 2006 17:39

Re: XML / XSLT Reihenfolge definieren.
 
Hallo,

mir war schon klar, dass dein Beispieldokument synthetisch ist. Was mein XSLT-Skript dir aber gezeigt haben sollte ist, dass du ein Sortierkriterium in deinem XML-Dokument brauchst. Wenn die gewünschte Ordnung nicht aus den Daten selbst abgeleitet werden kann, dann bleibt dir nichts anderes übrig, als die Knoten individuell zu ordnen.

Freundliche Grüße

StTüff 4. Dez 2006 08:37

Re: XML / XSLT Reihenfolge definieren.
 
Hallo!

OK. "Von den Daten ableiten" bedeutet aber, dass es in auf- oder absteigender Reihenfolge sein muss. Mir bringt es nichts, wenn ich die gewünschte Reihenfolge kenne, oder?

Wenn ich die Namen vor dem sortieren ersetzen würde, also z.B. ebeneB1 wird E1, ebeneB3 wird E2 und ebeneB2 wird E3, dann könnte ich sortieren und würde die gewünschte Reihenfolge erhalten. Anschließend könnte ich die Knotennamen wieder durch die richtigen ersetzen. Würde das gehen?

Gruß,

StTüff

StTüff 4. Dez 2006 09:32

Re: XML / XSLT Reihenfolge definieren.
 
OK. Ich glaube ich hab's jetzt selbst gelöst.

Basierend auf meinem ursprünglichen Ansatz mache ich nun folgendes:
XML-Code:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="ebeneA | @* ">
    <xsl:copy>
      <xsl:apply-templates select="@*"/>
      <xsl:apply-templates select="ebeneB1" />
      <xsl:apply-templates select="ebeneB3" />
      <xsl:apply-templates select="ebeneB2" />
    </xsl:copy>
  </xsl:template>
  <xsl:template match="ebeneB2 | ebeneB2/* | @* ">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>
  <xsl:template match="ebeneB1 | ebeneB1/* | @* ">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>
  <xsl:template match="ebeneB3 | ebeneB3/* | @* ">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>
Damit erhalte ich aus:
XML-Code:
<ebeneA att1="1">
  <ebeneB2 att4="1">
    <ebeneD att5="1">Hallo</ebeneD>
  </ebeneB2>
  <ebeneB3 att2="1">
    <ebeneC att3="1"/>
  </ebeneB3>
  <ebeneB1 att2="1">
    <ebeneC att3="1"/>
  </ebeneB1>
</ebeneA>
dieses Ergebnis (das damit in der gewünschten Reihenfolge ist und in dem trotzdem alle Knoten enthalten sind):
XML-Code:
<ebeneA att1="1">
  <ebeneB1 att2="1">
    <ebeneC att3="1"/>
  </ebeneB1>
  <ebeneB3 att2="1">
    <ebeneC att3="1"/>
  </ebeneB3>
  <ebeneB2 att4="1">
    <ebeneD att5="1">Hallo</ebeneD>
  </ebeneB2>
</ebeneA>
Gibt es Kritik oder Hinweise zu diesem Ergebnis? Wie gesagt: Ich bin hier "Neuling" und noch sehr unsicher. :drunken:

Gruß und vielen Dank für die Beiträge,

StTüff

[edit=Christian Seehase]Editiert, damit der Code wieder angezeigt wird. Mfg, Christian Seehase[/edit]


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:13 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz