it-swarm.com.de

Produzieren einer neuen Linie in XSLT

Ich möchte eine neue Zeile für die Textausgabe in XSLT erstellen. Irgendwelche Ideen?

187
Mithil

Der folgende XSL-Code erzeugt ein Zeilenvorschub (Zeilenvorschub) -Zeichen:

<xsl:text>&#xa;</xsl:text>

Für ein Wagenrücklauf verwenden Sie:

<xsl:text>&#xd;</xsl:text>
227
Florjon

Meine bevorzugte Methode dafür sieht ungefähr so ​​aus:

<xsl:stylesheet>

<xsl:output method='text'/>

<xsl:variable name='newline'><xsl:text>
</xsl:text></xsl:variable>

<!-- note that the layout there is deliberate -->

...

</xsl:stylesheet>

Wann immer Sie eine neue Zeile ausgeben möchten (möglicherweise in csv), können Sie Folgendes ausgeben:

<xsl:value-of select="concat(elem1,elem2,elem3,$newline)" />

Ich habe diese Technik bei der Ausgabe von SQL aus XML-Eingabe verwendet. Tatsächlich neige ich dazu, Variablen für Kommas, Anführungszeichen und Zeilenumbrüche zu erstellen.

48
Nic Gibson

Fügen Sie das Attribut Method = "text" in das xsl: output-Tag ein und fügen Sie an den entsprechenden Stellen Zeilenumbrüche in den Literalinhalt der XSL ein. Wenn Sie es vorziehen, den Quellcode Ihres XSL-Systems aufgeräumt zu halten, verwenden Sie die Entität &#10; wo Sie eine neue Zeile möchten.

45
AnthonyWJones

Sie können verwenden: <xsl:text>&#10;</xsl:text>

siehe das Beispiel

<xsl:variable name="module-info">
  <xsl:value-of select="@name" /> = <xsl:value-of select="@rev" />
  <xsl:text>&#10;</xsl:text>
</xsl:variable>

wenn Sie dies in eine Datei schreiben, z.

<redirect:write file="temp.prop" append="true">
  <xsl:value-of select="$module-info" />
</redirect:write>

diese Variable erzeugt eine neue Zeilendatei als:

commons-dbcp_commons-dbcp = 1.2.2
junit_junit = 4.4
org.easymock_easymock = 2.4
28
user878525

IMHO ist nicht mehr Info als @Florjon benötigt. Vielleicht bleiben ein paar kleine Details übrig, um zu verstehen, warum es manchmal bei uns nicht funktioniert.

Zunächst funktioniert der &#xa (Hex) oder &#10 (Dec) innerhalb eines <xsl:text/> Immer, aber Sie sehen ihn möglicherweise nicht.

  1. In einem HTML-Markup gibt es keine Zeilenumbrüche. Die Verwendung eines einfachen <br/> Reicht völlig aus. Andernfalls wird ein Leerzeichen angezeigt. Wenn Sie die Quelle im Browser anzeigen, erfahren Sie, was wirklich passiert ist. Es gibt jedoch Fälle, in denen Sie dieses Verhalten erwarten, insbesondere wenn der Verbraucher nicht direkt ein Browser ist. Sie möchten beispielsweise eine HTML-Seite erstellen und ihre Struktur mit leeren Zeilen und ID-Werten anzeigen, bevor Sie sie an den Browser senden.
  2. Denken Sie daran, wo Sie disable-output-escaping Verwenden müssen und wo nicht. Nehmen wir das folgende Beispiel, in dem ich eine XML aus einer anderen erstellen und ihre DTD aus einem Stylesheet deklarieren musste.

Die erste Version maskiert die Zeichen (Standard für xsl: text)

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" indent="yes" encoding="utf-8"/>

    <xsl:template match="/">
        <xsl:text>&lt;!DOCTYPE Subscriptions SYSTEM "Subscriptions.dtd"&gt;&#xa;&#xa;&#xd;</xsl:text>
        <xsl:copy>
            <xsl:apply-templates select="*" mode="copy"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="@*|node()" mode="copy">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()" mode="copy"/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

und hier ist das Ergebnis:

<?xml version="1.0" encoding="utf-8"?>
&lt;!DOCTYPE Subscriptions SYSTEM "Subscriptions.dtd"&gt;

&#13;<Subscriptions>
    <User id="1"/>   
</Subscriptions>

Ok, es macht das, was wir erwarten. Es wird ausgeblendet, damit die Zeichen, die wir verwendet haben, richtig angezeigt werden. Die Formatierung des XML-Teils im Stammknoten wird von ident="yes" Übernommen. Aber bei näherer Betrachtung wir sehen, dass das Newline-Zeichen &#xa Nicht maskiert und übersetzt wurde, wodurch ein doppelter Zeilenvorschub ausgeführt wurde! Ich habe keine Erklärung dafür, wird gut zu wissen sein. Jemand?

Die zweite Version entgeht den Charakteren nicht und sie produzieren, wofür sie bestimmt sind. Die Änderung war:

<xsl:text disable-output-escaping="yes">&lt;!DOCTYPE Subscriptions SYSTEM "Subscriptions.dtd"&gt;&#xa;&#xa;&#xd;</xsl:text>

und hier ist das Ergebnis:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE Subscriptions SYSTEM "Subscriptions.dtd">

<Subscriptions>
    <User id="1"/>   
</Subscriptions>

und das wird ok sein. Sowohl cr als auch lf werden korrekt gerendert.

  1. Vergiss nicht, dass es sich um nl handelt, nicht um crlf (nl=lf). Mein erster Versuch war, nur cr: &#xd Zu verwenden, und während die Ausgabe-XML von DOM ordnungsgemäß validiert wurde.

Ich habe eine beschädigte XML-Datei angezeigt:

<?xml version="1.0" encoding="utf-8"?>
<Subscriptions>riptions SYSTEM "Subscriptions.dtd">
    <User id="1"/>   
</Subscriptions>

Der DOM-Parser hat Steuerzeichen ignoriert, das gerenderte jedoch nicht. Ich verbrachte einige Zeit damit, meinen Kopf zu stoßen, bevor mir klar wurde, wie dumm ich das nicht sah!

Für die Aufzeichnung verwende ich eine Variable innerhalb des Körpers mit beiden CRLF, um 100% sicher zu sein, dass es überall funktioniert.

5
Agoun

Ich habe die DOCTYPE Direktive hinzugefügt, die Sie hier sehen:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xsl:stylesheet [
  <!ENTITY nl "&#xa;">
]>
<xsl:stylesheet xmlns:x="http://www.w3.org/2005/02/query-test-XQTSCatalog"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                version="2.0">

Dies ermöglicht es mir, &nl; anstatt &#xa;, um eine neue Zeile in der Ausgabe zu erstellen. Wie bei anderen Lösungen wird dies normalerweise in einem <xsl:text> Etikett.

3
Sam Harwell

Ich habe aus meiner Erfahrung heraus bemerkt, dass das Erzeugen einer neuen Linie INNERHALB a <xsl:variable> Klausel funktioniert nicht. Ich habe versucht, etwas zu tun wie:

<xsl:variable name="myVar">
  <xsl:choose>
    <xsl:when test="@myValue != ''">
      <xsl:text>My value: </xsl:text>
      <xsl:value-of select="@myValue" />
      <xsl:text></xsl:text> <!--NEW LINE-->
      <xsl:text>My other value: </xsl:text>
      <xsl:value-of select="@myOtherValue" />
    </xsl:when>
  </xsl:choose>
<xsl:variable>

<div>
  <xsl:value-of select="$myVar"/>
</div>

Alles, was ich versucht habe, in diese "neue Zeile" einzufügen (das leere <xsl:text> node) hat einfach nicht funktioniert (einschließlich der meisten einfacheren Vorschläge auf dieser Seite), ganz zu schweigen von der Tatsache, dass HTML dort einfach nicht funktioniert, und ich musste es schließlich in zwei Variablen aufteilen und sie außerhalb von aufrufen <xsl:variable> Umfang und setzen Sie ein einfaches <br/> zwischen ihnen, d.h.

<xsl:variable name="myVar1">
  <xsl:choose>
    <xsl:when test="@myValue != ''">
      <xsl:text>My value: </xsl:text>
      <xsl:value-of select="@myValue" />
    </xsl:when>
  </xsl:choose>
<xsl:variable>

<xsl:variable name="myVar2">
  <xsl:choose>
    <xsl:when test="@myValue != ''">
      <xsl:text>My other value: </xsl:text>
      <xsl:value-of select="@myOtherValue" />
    </xsl:when>
  </xsl:choose>
<xsl:variable>

<div>
  <xsl:value-of select="$myVar1"/>
  <br/>
  <xsl:value-of select="$myVar2"/>
</div>

Ja, ich weiß, es ist nicht die raffinierteste Lösung, aber es funktioniert, wenn ich nur meine teile frustration Erfahrung mit XSLs;)

2
ShayLivyatan

Du kannst es versuchen,

<xsl:text>&#xA;</xsl:text>

Es wird klappen.

2

Ich habe einen Unterschied zwischen wörtlichen Zeilenumbrüchen in <xsl:text> Und wörtlichen Zeilenumbrüchen mit &#xA; Festgestellt.

Während wörtliche Zeilenumbrüche in meiner Umgebung einwandfrei funktionierten (sowohl mit dem sächsischen als auch dem standardmäßigen Java XSLT-Prozessor), schlug mein Code fehl, wenn er von einer anderen Gruppe in einer .NET-Umgebung ausgeführt wurde.

Durch das Wechseln zu Entitäten (&#xA;) Wurde mein Dateierzeugungscode sowohl auf Java als auch auf .NET konsistent ausgeführt.

Literal Newlines sind außerdem anfällig für eine Neuformatierung durch IDEs und können versehentlich verloren gehen, wenn die Datei von jemandem gepflegt wird, der nicht informiert ist.

2
Agnes

Ich habe die Methode von Nic Gibson übernommen, das war schon immer meine Lieblingsmethode:

<xsl:variable name='nl'><xsl:text>
</xsl:text></xsl:variable>

Ich habe jedoch die Ant-Task <echoxml> verwendet, um Stylesheets zu erstellen und sie für Dateien auszuführen. Die Aufgabe führt Attributwertvorlagen aus, z. $ {DSTAMP}, wird aber auch Ihre XML neu formatieren. In einigen Fällen ist der Entity-Verweis vorzuziehen.

<xsl:variable name='nl'><xsl:text>&#xa;</xsl:text></xsl:variable>
1

Ich konnte nicht einfach das <xsl:text>&#xa;</xsl:text> Ansatz, denn wenn ich die XML-Datei mit XSLT formatiere, verschwindet die Entität. Also musste ich einen etwas runderen Ansatz mit Variablen verwenden

<xsl:variable name="nl" select="'&#10;'"/>
<xsl:template match="/">
    <xsl:value-of select="$nl" disable-output-escaping="no"/>
    <xsl:apply-templates select="*"/>
</xsl:template>
1