Whitespace-Stripping mit XslCompiledTransform

8

Ich versuche, eine große App von XslTransform zu kompilierten xsl-Dateien und XslCompiledTransform zu migrieren.

Die App verwendet Xsl , um HTML-Dateien zu erstellen, und die Transformationsdaten ( Xml ) wurden an das Xsl mit einem XmlDataDocument übergeben, das von der Datenbank zurückgegeben wurde.

Ich habe alles geändert, jetzt mache ich es (zumindest vorübergehend):

C #

%Vor%

XSL (nur ein Beispiel)

%Vor%

Problem

Das funktioniert, aber die xsl streift die Leerzeichen zwischen den Tags ab und gibt Folgendes aus:

%Vor%

Ich habe es versucht:

  • Verwendung von xml:space="preserve" , aber ich konnte es nicht zum Laufen bringen
  • Das OutputSettings überschrieben, aber ich habe keine guten Ergebnisse bekommen (vielleicht habe ich etwas verpasst)
  • Mit xsl:output method="xml" , und das funktioniert, aber erstellt selbstschließende Tags und viele andere Probleme

Ich weiß also nicht, was ich tun soll. Vielleicht mache ich etwas nicht richtig. Jede Hilfe ist sehr geschätzt.

Danke!

BEARBEITEN

Nur für zukünftige Referenzen, wenn Sie dieses Problem angehen wollen und jedes XSL intakt lassen, könnte man diese C # Klasse ausprobieren, die ich geschrieben habe, genannt CustomHtmlWriter .

Grundsätzlich habe ich von XmlTextWriter erweitert und ändere die Methoden, die start und end jedes Tags schreiben.

In diesem speziellen Fall würden Sie es wie folgt verwenden:

%Vor%

Ich hoffe, es hilft jemandem.

    
NicoSantangelo 31.08.2012, 15:40
quelle

4 Antworten

4

Ich. Lösung 1 :

Lassen Sie mich zuerst das Problem hier analysieren :

Gegeben dieses Quell-XML-Dokument (erfunden, wie Sie es nicht angegeben haben):

%Vor%

Diese Umwandlung :

%Vor%

reproduziert genau das Problem - das Ergebnis ist:

%Vor%

Kommentieren Sie jetzt einfach die kommentierte Vorlage und kommentieren Sie die erste Vorlage:

%Vor%

Das Ergebnis hat die gewünschte Einrückung :

%Vor%

Und das war Lösung 1

II. Lösung 2 :

Diese Lösung kann die erforderlichen Änderungen an Ihrem vorhandenen XSLT-Code auf ein Minimum reduzieren:

Dies ist eine Transformation mit zwei Durchgängen :

%Vor%

Die Idee ist, dass wir den vorhandenen Code nicht einmal anfassen, sondern seine Ausgabe erfassen und nur ein paar Zeilen zusätzlichen Code verwenden. Wir formatieren die Ausgabe so, dass sie das gewünschte endgültige Aussehen hat.

Wenn diese Transformation auf dasselbe XML-Dokument angewendet wird, wird dasselbe gewünschte Ergebnis erzeugt:

%Vor%

Zum Schluss wird hier gezeigt, wie diese kleine Änderung eingeführt werden kann, ohne überhaupt vorhandenen XSLT-Code zu berühren:

Lassen Sie uns diesen vorhandenen Code in c:\temp\delete\existing.xsl :

haben %Vor%

Wenn wir das ausführen, erhalten wir die problematische Ausgabe .

Anstatt existing.xsl auszuführen, führen wir jetzt diese Umwandlung aus :

%Vor%

Das Ergebnis ist das gewünschte und der vorhandene Code ist überhaupt nicht betroffen :

%Vor%

Erläuterung :

  1. Wir importieren jeden vorhandenen Code, der sich auf der obersten Ebene der Import-Rangfolge-Hierarchie befindet (nicht von anderen Stylesheets importiert). Verwenden Sie dazu xsl:import .

  2. Wir erfassen die Ausgabe der vorhandenen Transformation in einer Variablen. Es hat das berüchtigte RTF ( Ergebnisbaumfragment ) muss in regulären Baum konvertiert werden, um weiter verarbeitet zu werden.

  3. Der Schlüsselmoment ist die Durchführung von xsl:apply-imports beim Erfassen der Ausgabe der Transformation. Dies stellt sicher, dass jede Vorlage aus dem vorhandenen Code (auch eine, die wir überschreiben - wie die Vorlage, die / entspricht) zur Ausführung ausgewählt wird, wie in dem Fall, wenn die vorhandene Transformation von ihr selbst ausgeführt wird.)

  4. Wir konvertieren das RTF in einen regulären Baum, indem wir msxsl:node-set() Erweiterungsfunktion (XslCompiledTransform unterstützt auch die EXSLT node-set() Erweiterungsfunktion).

  5. Wir führen unsere kosmetischen Anpassungen an dem so hergestellten regulären Baum durch.

Beachten Sie :

Dies ist ein allgemeiner Algorithmus zum Nachbearbeiten vorhandener Transformationen, ohne den vorhandenen Code zu berühren .

    
Dimitre Novatchev 02.09.2012, 22:12
quelle
1

Ich denke, das Problem ist:

%Vor%

Wenn ich mich richtig erinnere, versucht html, sich nur um Whitespaces zu kümmern, was wichtig ist, um den HTML-Code anzuzeigen.

Wenn Sie versuchen:

%Vor%

Dann sollte es den eingerückten Leerraum erzeugen, den Sie erwarten.

    
Nick Jones 31.08.2012 16:37
quelle
1

Whitespace-Textknoten im Stylesheet werden immer ignoriert, sofern sie nicht in xsl: text enthalten sind. Wenn Sie Leerzeichen in den Ergebnisbaum ausgeben möchten, verwenden Sie xsl: text.

(Es ist auch möglich, xml: space="preserve" im Stylesheet zu verwenden, aber das ist im Allgemeinen nicht ratsam, da es unerwünschte Nebenwirkungen hat.)

    
Michael Kay 31.08.2012 18:36
quelle
1

Ich kann mich nicht mehr an die Details der XML / XSLT-Speicherplatzerhaltung erinnern, aber eine Instanz, bei der Whitespace eher verworfen wird, befindet sich zwischen Elementen, bei denen kein Leerzeichen vorhanden ist (dh Leerzeichen nur Text) Knoten, wie der zwischen </a> und </xsl:for-each> ). Sie können dies verhindern, indem Sie das Element <xsl:text> verwenden.

Zum Beispiel nach

%Vor%

setzen

%Vor%

i.e. ein wörtliches Zeilenendezeichen.

Entspricht das Ihren Anforderungen?

    
LarsH 31.08.2012 16:03
quelle