web-dev-qa-db-fra.com

Produire une nouvelle ligne en XSLT

Je veux produire une nouvelle ligne pour la sortie de texte dans XSLT. Des idées?

187
Mithil

Le code XSL suivant produira un caractère nouvelle ligne (saut de ligne):

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

Pour un retour chariot , utilisez:

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

Ma méthode préférée pour ce faire ressemble à quelque chose comme:

<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>

Ensuite, chaque fois que vous voulez sortir une nouvelle ligne (peut-être en csv), vous pouvez sortir quelque chose comme ce qui suit:

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

J'ai utilisé cette technique lors de la sortie de SQL à partir d'une entrée XML. En fait, j'ai tendance à créer des variables pour les virgules, les guillemets et les nouvelles lignes.

48
Nic Gibson

Incluez l'attribut Method = "text" sur la balise xsl: output et incluez des nouvelles lignes dans votre contenu littéral dans le fichier XSL aux points appropriés. Si vous préférez garder le code source de votre fichier XSL bien rangé, utilisez l’entité &#10; où vous souhaitez une nouvelle ligne.

45
AnthonyWJones

Vous pouvez utiliser: <xsl:text>&#10;</xsl:text>

voir l'exemple

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

si vous écrivez ceci dans un fichier, par exemple.

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

cette variable produira une nouvelle ligne infile comme:

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

IMHO pas plus d'informations que @Florjon a donné est nécessaire. Il reste peut-être quelques petits détails pour comprendre pourquoi cela peut parfois ne pas fonctionner pour nous.

Tout d'abord, le &#xa (hex) ou &#10 (dec) à l'intérieur d'un <xsl:text/> fonctionnera toujours, mais il est possible que vous ne le voyiez pas.

  1. Il n'y a pas de nouvelle ligne dans un balisage HTML. L'utilisation d'un simple <br/> suffira. Sinon, vous verrez un espace blanc. Voir la source depuis le navigateur vous dira ce qui s’est réellement passé. Cependant, dans certains cas, vous vous attendez à ce comportement, notamment si le consommateur n'est pas directement un navigateur. Par exemple, vous voulez créer une page HTML et afficher sa structure correctement formatée avec des lignes vides et des identifiants avant de la transmettre au navigateur.
  2. Rappelez-vous où vous devez utiliser disable-output-escaping et où vous ne l'utilisez pas. Prenons l'exemple suivant où je devais créer un fichier XML à partir d'un autre et déclarer sa DTD à partir d'une feuille de style.

La première version échappe aux caractères (par défaut pour 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>

et voici le résultat:

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

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

Ok, il fait ce que nous attendons, s’échapper est fait pour que les caractères que nous avons utilisés soient affichés correctement. Le formatage de la pièce XML à l'intérieur du noeud racine est géré par ident="yes". Mais en regardant de plus près on voit que le caractère de nouvelle ligne &#xa n'a pas été échappé et traduit tel quel, effectuant un double saut de ligne! Je n'ai pas d'explication à ce sujet, ce sera bon à savoir. N'importe qui?

La deuxième version n'échappe pas aux personnages, ils produisent donc ce à quoi ils sont destinés. Le changement effectué était:

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

et voici le résultat:

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

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

et ça ira. Cr et lf sont correctement rendus.

  1. N'oubliez pas que nous parlons de nl, pas crlf (nl=lf). Ma première tentative a été d'utiliser uniquement cr: &#xd et que le xml de sortie était correctement validé par DOM.

Je visionnais un xml corrompu:

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

L'analyseur DOM n'a pas tenu compte des caractères de contrôle, mais pas le rendu. J'ai passé pas mal de temps à me cogner la tête avant de réaliser à quel point je ne voyais pas ça!

Pour mémoire, j'utilise une variable à l'intérieur du corps avec les deux CRLF juste pour être sûr à 100% que cela fonctionnera partout.

5
Agoun

J'ai ajouté la directive DOCTYPE que vous voyez ici:

<?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">

Cela me permet d’utiliser &nl; au lieu de &#xa; pour produire une nouvelle ligne dans la sortie. Comme d’autres solutions, elle est généralement placée dans une balise <xsl:text>.

3
Sam Harwell

D'après mon expérience, j'ai constaté que la production d'une nouvelle ligne INSIDE une clause <xsl:variable> ne fonctionne pas. J'essayais de faire quelque chose comme:

<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>

Tout ce que j'ai essayé de mettre dans cette "nouvelle ligne" (le noeud vide <xsl:text>) ne fonctionne tout simplement pas (y compris la plupart des suggestions plus simples de cette page), sans oublier le fait que HTML ne fonctionne tout simplement pas là-bas, j’ai donc dû le scinder en 2 variables, les appeler en dehors de la portée de <xsl:variable> et placer un simple <br/> entre elles, c’est-à-dire:

<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>

Ouais, je sais, ce n’est pas la solution la plus sophistiquée mais ça marche, je partage juste mon frustration expérience avec les XSL;)

2
ShayLivyatan

Tu peux essayer,

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

Ça va marcher.

2
BIBIN K ONANKUNJU

J'ai trouvé une différence entre les nouvelles lignes littérales dans <xsl:text> et les nouvelles lignes littérales utilisant &#xA;.

Bien que les nouvelles lignes littérales fonctionnaient correctement dans mon environnement (en utilisant à la fois Saxon et le processeur par défaut Java XSLT), mon code échouait lorsqu'il était exécuté par un autre groupe exécuté dans un environnement .NET.

Passer à des entités (&#xA;) a permis à mon code de génération de fichier de fonctionner de manière cohérente à la fois sur Java et sur .NET.

En outre, les sauts de ligne littéraux sont susceptibles d'être reformatés par les IDE et peuvent se perdre par inadvertance lorsque le fichier est maintenu par une personne "pas au courant".

2
Agnes

J'appuie la méthode de Nic Gibson, cela a toujours été ma préférée:

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

Cependant, j'ai utilisé la tâche Ant <echoxml> pour créer des feuilles de style et les exécuter sur des fichiers. La tâche utilisera des modèles de valeur d'attribut, par exemple: $ {DSTAMP}, mais va également reformater votre xml, donc dans certains cas, la référence à une entité est préférable.

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

Je ne pouvais pas simplement utiliser l'approche <xsl:text>&#xa;</xsl:text> parce que si je formate le fichier XML à l'aide de XSLT, l'entité disparaîtra. Je devais donc utiliser une approche légèrement plus ronde en utilisant des variables

<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
Archimedes Trajano