+1: jest to bardziej niezawodne niż <xsl:text>podejście zawierające nową linię, jeśli użyjesz czegoś, co może ponownie sformatować plik XSL i zepsuć się spacją.
Ian Roberts
49
Moja ulubiona metoda robienia tego wygląda mniej więcej tak:
<xsl:stylesheet><xsl:outputmethod='text'/><xsl:variablename='newline'><xsl:text></xsl:text></xsl:variable><!-- note that the layout there is deliberate -->
...
</xsl:stylesheet>
Następnie, ilekroć chcesz wypisać nowy wiersz (być może w csv), możesz wypisać coś takiego:
Użyłem tej techniki podczas wyprowadzania sql z wejścia xml. W rzeczywistości staram się tworzyć zmienne dla przecinków, cudzysłowów i znaków nowej linii.
Pamiętaj, że poniższa odpowiedź Florjon jest znacznie bardziej stabilna niż moja.
Nic Gibson,
1
Prawdopodobnie warto dodać deklarację xml:space="preserve"do xsl:textelementu w celu zwiększenia stabilności, ale zgodzę się, że odpowiedź @ Florjon jest prawdopodobnie bezpieczniejsza.
Flynn1179
Wadą tego rozwiązania jest także włączenie wgłębień, które mogą być niepożądane.
wmassingham,
47
Dołącz atrybut Method = "text" do znacznika wyjściowego xsl: i wstaw nowe znaki w swojej dosłownej treści do XSL w odpowiednich punktach. Jeśli wolisz zachować kod źródłowy swojej XSL schludny, użyj encji, w której chcesz nową linię.
IMHO nie wymaga więcej informacji niż @Florjon. Być może pozostawiono kilka drobnych szczegółów, aby zrozumieć, dlaczego czasami może to nie działać.
Przede wszystkim 
 (hex) lub 
(dec) wewnątrz <xsl:text/>zawsze będzie działać, ale możesz go nie zobaczyć.
W znacznikach HTML nie ma znaku nowej linii. Za pomocą prostego<br/> wystarczy. W przeciwnym razie zobaczysz białą przestrzeń. Wyświetlenie źródła z przeglądarki powie Ci, co się naprawdę wydarzyło. Są jednak przypadki, w których można oczekiwać takiego zachowania, zwłaszcza jeśli konsument nie jest bezpośrednio przeglądarką. Na przykład, chcesz utworzyć stronę HTML i wyświetlić jej strukturę sformatowaną ładnie z pustymi liniami i identyfikatorami przed podaniem jej do przeglądarki.
Pamiętaj, gdzie chcesz użyć disable-output-escaping a gdzie nie. Weźmy następujący przykład, w którym musiałem utworzyć plik XML z innego i zadeklarować jego DTD z arkusza stylów.
Pierwsza wersja nie zawiera znaków (domyślnie dla xsl: text)
<xsl:stylesheetxmlns:xsl="http://www.w3.org/1999/XSL/Transform"version="1.0"><xsl:outputmethod="xml"indent="yes"encoding="utf-8"/><xsl:templatematch="/"><xsl:text><!DOCTYPE Subscriptions SYSTEM "Subscriptions.dtd">


</xsl:text><xsl:copy><xsl:apply-templatesselect="*"mode="copy"/></xsl:copy></xsl:template><xsl:templatematch="@*|node()"mode="copy"><xsl:copy><xsl:apply-templatesselect="@*|node()"mode="copy"/></xsl:copy></xsl:template></xsl:stylesheet>
a oto wynik:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE Subscriptions SYSTEM "Subscriptions.dtd">
<Subscriptions><Userid="1"/></Subscriptions>
Ok, robi to, czego oczekujemy, ucieczka jest wykonywana, aby używane znaki były wyświetlane poprawnie. Formatowanie części XML w węźle głównym jest obsługiwane przez ident="yes". Ale przy bliższym spojrzeniu widzimy, że znak nowej linii
 nie został ocalony i przetłumaczony , wykonując podwójny przesuw linii! Nie mam wyjaśnienia na ten temat, dobrze będzie wiedzieć. Ktoś?
Druga wersja nie ucieka bohaterom, więc produkują to, do czego są przeznaczeni. Dokonana zmiana to:
<xsl:textdisable-output-escaping="yes"><!DOCTYPE Subscriptions SYSTEM "Subscriptions.dtd">


</xsl:text>
a oto wynik:
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE Subscriptions SYSTEM "Subscriptions.dtd"><Subscriptions><Userid="1"/></Subscriptions>
i będzie dobrze. Zarówno cr, jak i lf są poprawnie renderowane.
Nie zapominaj, że mówimy nl, a nie crlf( nl=lf). Moją pierwszą próbą było użycie tylko cr: 
i podczas gdy wyjściowy plik XML został poprawnie sprawdzony przez DOM.
Przeglądałem uszkodzony plik XML:
<?xml version="1.0" encoding="utf-8"?><Subscriptions>riptions SYSTEM "Subscriptions.dtd">
<Userid="1"/></Subscriptions>
Parser DOM zignorował znaki sterujące, ale renderowany nie. Spędziłem trochę czasu, uderzając się w głowę, zanim zdałem sobie sprawę, jak głupio tego nie widziałem!
Dla przypomnienia używam zmiennej wewnątrz ciała z obydwoma CRLF, aby mieć 100% pewność, że będzie działać wszędzie.
Używam jednak zadania Ant <echoxml> do tworzenia arkuszy stylów i uruchamiania ich z plikami. Zadanie wykona szablony wartości atrybutów, np. $ {DSTAMP}, ale również sformatuje twój plik xml, więc w niektórych przypadkach wskazane jest odwołanie do encji.
Jeśli użyjesz zmiennej, lepiej byłoby użyć selectzamiast niej xsl:text. Przykład: <xsl:variable name="nl" select="'
'"/>W ten sposób nie tworzysz niepotrzebnego RTF (fragment drzewa wyników).
Daniel Haley,
2
Znalazłem różnicę między dosłownymi znakami nowej linii <xsl:text>i dosłownymi znakami nowej linii
 .
Podczas gdy dosłownie nowe wiersze działały dobrze w moim środowisku (przy użyciu zarówno saskiego, jak i domyślnego procesora Java XSLT), mój kod zawiódł, gdy został wykonany przez inną grupę działającą w środowisku .NET.
Zmiana na podmioty (
 ) sprawiła, że mój kod generowania plików działał spójnie zarówno w Javie, jak i .NET.
Ponadto dosłowne znaki nowej linii są podatne na formatowanie przez IDE i mogą zostać przypadkowo utracone, gdy plik jest utrzymywany przez kogoś „nie znanego”.
Zauważyłem z mojego doświadczenia wynika, że produkcja nowej linii INSIDE o <xsl:variable>klauzuli nie działa. Próbowałem zrobić coś takiego:
<xsl:variablename="myVar"><xsl:choose><xsl:whentest="@myValue != ''"><xsl:text>My value: </xsl:text><xsl:value-ofselect="@myValue"/><xsl:text></xsl:text><!--NEW LINE--><xsl:text>My other value: </xsl:text><xsl:value-ofselect="@myOtherValue"/></xsl:when></xsl:choose><xsl:variable><div><xsl:value-ofselect="$myVar"/></div>
Wszystko, co próbowałem umieścić w „nowej linii” (pustym <xsl:text>węźle) po prostu nie działało (w tym większość prostszych sugestii na tej stronie), nie wspominając już o tym, że HTML po prostu tam nie działa, więc ostatecznie musiał podzielić go na 2 zmienne, wywołać je poza <xsl:variable>zakresem i umieścić prostą <br/>między nimi, tj .:
<xsl:variablename="myVar1"><xsl:choose><xsl:whentest="@myValue != ''"><xsl:text>My value: </xsl:text><xsl:value-ofselect="@myValue"/></xsl:when></xsl:choose><xsl:variable><xsl:variablename="myVar2"><xsl:choose><xsl:whentest="@myValue != ''"><xsl:text>My other value: </xsl:text><xsl:value-ofselect="@myOtherValue"/></xsl:when></xsl:choose><xsl:variable><div><xsl:value-ofselect="$myVar1"/><br/><xsl:value-ofselect="$myVar2"/></div>
Tak, wiem, to nie jest najbardziej wyrafinowane rozwiązanie, ale działa, po prostu dzielę się swoją frustracją z XSL;)
Nie mogłem po prostu użyć tego <xsl:text>
</xsl:text>podejścia, ponieważ jeśli sformatuję plik XML za pomocą XSLT, encja zniknie. Musiałem więc użyć nieco więcej rundy na temat podejścia wykorzystującego zmienne
Odpowiedzi:
Poniższy kod XSL utworzy znak nowej linii (znak wiersza):
Do zwrotu karetki użyj:
źródło
<xsl:text>
podejście zawierające nową linię, jeśli użyjesz czegoś, co może ponownie sformatować plik XSL i zepsuć się spacją.Moja ulubiona metoda robienia tego wygląda mniej więcej tak:
Następnie, ilekroć chcesz wypisać nowy wiersz (być może w csv), możesz wypisać coś takiego:
Użyłem tej techniki podczas wyprowadzania sql z wejścia xml. W rzeczywistości staram się tworzyć zmienne dla przecinków, cudzysłowów i znaków nowej linii.
źródło
xml:space="preserve"
doxsl:text
elementu w celu zwiększenia stabilności, ale zgodzę się, że odpowiedź @ Florjon jest prawdopodobnie bezpieczniejsza.Dołącz atrybut Method = "text" do znacznika wyjściowego xsl: i wstaw nowe znaki w swojej dosłownej treści do XSL w odpowiednich punktach. Jeśli wolisz zachować kod źródłowy swojej XSL schludny, użyj encji, w
której chcesz nową linię.źródło
Możesz użyć:
<xsl:text> </xsl:text>
patrz przykład
jeśli napiszesz to w pliku np
ta zmienna utworzy nowy infiltr linii jako:
źródło
IMHO nie wymaga więcej informacji niż @Florjon. Być może pozostawiono kilka drobnych szczegółów, aby zrozumieć, dlaczego czasami może to nie działać.
Przede wszystkim


(hex) lub

(dec) wewnątrz<xsl:text/>
zawsze będzie działać, ale możesz go nie zobaczyć.<br/>
wystarczy. W przeciwnym razie zobaczysz białą przestrzeń. Wyświetlenie źródła z przeglądarki powie Ci, co się naprawdę wydarzyło. Są jednak przypadki, w których można oczekiwać takiego zachowania, zwłaszcza jeśli konsument nie jest bezpośrednio przeglądarką. Na przykład, chcesz utworzyć stronę HTML i wyświetlić jej strukturę sformatowaną ładnie z pustymi liniami i identyfikatorami przed podaniem jej do przeglądarki.disable-output-escaping
a gdzie nie. Weźmy następujący przykład, w którym musiałem utworzyć plik XML z innego i zadeklarować jego DTD z arkusza stylów.Pierwsza wersja nie zawiera znaków (domyślnie dla xsl: text)
a oto wynik:
Ok, robi to, czego oczekujemy, ucieczka jest wykonywana, aby używane znaki były wyświetlane poprawnie. Formatowanie części XML w węźle głównym jest obsługiwane przez
ident="yes"
. Ale przy bliższym spojrzeniu widzimy, że znak nowej linii

nie został ocalony i przetłumaczony , wykonując podwójny przesuw linii! Nie mam wyjaśnienia na ten temat, dobrze będzie wiedzieć. Ktoś?Druga wersja nie ucieka bohaterom, więc produkują to, do czego są przeznaczeni. Dokonana zmiana to:
a oto wynik:
i będzie dobrze. Zarówno cr, jak i lf są poprawnie renderowane.
nl
, a niecrlf
(nl=lf
). Moją pierwszą próbą było użycie tylko cr:
i podczas gdy wyjściowy plik XML został poprawnie sprawdzony przez DOM.Przeglądałem uszkodzony plik XML:
Parser DOM zignorował znaki sterujące, ale renderowany nie. Spędziłem trochę czasu, uderzając się w głowę, zanim zdałem sobie sprawę, jak głupio tego nie widziałem!
Dla przypomnienia używam zmiennej wewnątrz ciała z obydwoma CRLF, aby mieć 100% pewność, że będzie działać wszędzie.
źródło
Dodałem
DOCTYPE
dyrektywę, którą widzicie tutaj:To pozwala mi użyć
&nl;
zamiast

tworzyć nowy wiersz w danych wyjściowych. Podobnie jak inne rozwiązania, zwykle umieszcza się go w<xsl:text>
tagu.źródło
Możesz spróbować,
To będzie działać.
źródło
Popieram metodę Nic Gibsona, zawsze była to moja ulubiona:
Używam jednak zadania Ant <echoxml> do tworzenia arkuszy stylów i uruchamiania ich z plikami. Zadanie wykona szablony wartości atrybutów, np. $ {DSTAMP}, ale również sformatuje twój plik xml, więc w niektórych przypadkach wskazane jest odwołanie do encji.
źródło
select
zamiast niejxsl:text
. Przykład:<xsl:variable name="nl" select="'
'"/>
W ten sposób nie tworzysz niepotrzebnego RTF (fragment drzewa wyników).Znalazłem różnicę między dosłownymi znakami nowej linii
<xsl:text>
i dosłownymi znakami nowej linii

.Podczas gdy dosłownie nowe wiersze działały dobrze w moim środowisku (przy użyciu zarówno saskiego, jak i domyślnego procesora Java XSLT), mój kod zawiódł, gdy został wykonany przez inną grupę działającą w środowisku .NET.
Zmiana na podmioty (


) sprawiła, że mój kod generowania plików działał spójnie zarówno w Javie, jak i .NET.Ponadto dosłowne znaki nowej linii są podatne na formatowanie przez IDE i mogą zostać przypadkowo utracone, gdy plik jest utrzymywany przez kogoś „nie znanego”.
źródło
Zauważyłem z mojego doświadczenia wynika, że produkcja nowej linii INSIDE o
<xsl:variable>
klauzuli nie działa. Próbowałem zrobić coś takiego:Wszystko, co próbowałem umieścić w „nowej linii” (pustym
<xsl:text>
węźle) po prostu nie działało (w tym większość prostszych sugestii na tej stronie), nie wspominając już o tym, że HTML po prostu tam nie działa, więc ostatecznie musiał podzielić go na 2 zmienne, wywołać je poza<xsl:variable>
zakresem i umieścić prostą<br/>
między nimi, tj .:Tak, wiem, to nie jest najbardziej wyrafinowane rozwiązanie, ale działa, po prostu dzielę się swoją
frustracjąz XSL;)źródło
Nie mogłem po prostu użyć tego
<xsl:text>
</xsl:text>
podejścia, ponieważ jeśli sformatuję plik XML za pomocą XSLT, encja zniknie. Musiałem więc użyć nieco więcej rundy na temat podejścia wykorzystującego zmienneźródło
po prostu dodaj ten tag:
mi to pasuje ;) .
źródło