użyj xsl do wyświetlania zwykłego tekstu
Potrzebowałem użyć XSL do wygenerowania prostego tekstu wyjściowego z XML. Ponieważ nie znalazłem żadnego dobrego, zwięzłego przykładu w Internecie, postanowiłem opublikować moje rozwiązanie tutaj. Wszelkie linki odnoszące się do lepszego przykładu będą oczywiście mile widziane:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" >
<xsl:output method="text" omit-xml-declaration="yes" indent="no"/>
<xsl:template match="/">
<xsl:for-each select="script/command" xml:space="preserve">at -f <xsl:value-of select="username"/> <xsl:value-of select="startTime/@hours"/>:<xsl:value-of select="startTime/@minutes"/> <xsl:value-of select="startDate"/><xsl:text>
</xsl:text></xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Kilka ważnych rzeczy, które pomogły mi tutaj:
- użycie xsl: output do pominięcia standardowej deklaracji na początku dokumentu wyjściowego
- użycie atrybutu XML: space= "preserve" do zachowania dowolnego whitespace napisałem wewnątrz znacznika xsl: for-each. Wymagało to od mnie również napisania całego kodu w ramach znacznika for-each, w tym również tego znacznika, w jednej linii (z wyjątkiem podziału linii).
- użycie do wstawiania podziału linii-ponownie musiałem pominąć standardowe wcięcia xml tutaj.
Wynikowe i pożądane wyjście dla tego xslt było:
At-F alluser 23:58 17.4.2010
at-f ggroup67 7: 58 28.4.2010
at-f ggroup70 15: 58 18.4.2010
at-F alluser 23:58 18.4.2010
at-f ggroup61 7: 58 22.9.2010
at-f ggroup60 23: 58 21.9.2010
at-F alluser 3:58 22.9.2010
Jak już powiedziałem, wszelkie sugestie, jak zrobić to bardziej elegancko, będą mile widziane.
KONTYNUACJA 2011-05-08:
Oto typ XML, który traktuję:
<script xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="script.xsd">
<command>
<username>alluser</username>
<startTime minutes="58" hours="23"/>
<startDate>17.4.2010</startDate>
</command>
</script>
2 answers
- można zdefiniować szablon do dopasowania na
script/command
i wyeliminowaćxsl:for-each
-
concat()
może być użyty do skrócenia wyrażenia i uniknięcia jawnego wstawiania tak wielu elementów<xsl:text>
i<xsl:value-of>
. - użycie referencji encji


do powrotu karetki, zamiast polegania na zachowaniu podziału linii między elementem<xsl:text>
jest nieco bezpieczniejsze, ponieważ formatowanie kodu nie zepsuje podziałów linii. Również, dla mnie, to czyta się jako wyraźny podział linii i jest łatwiejsze aby zrozumieć intencje.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format" >
<xsl:output method="text" omit-xml-declaration="yes" indent="no"/>
<xsl:template match="script/command">
<xsl:value-of select="concat('at -f '
,username
,' '
,startTime/@hours
,':'
,startTime/@minutes
,' '
,startDate
,'
')"/>
</xsl:template>
</xsl:stylesheet>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-06 11:26:38
Po prostu dla zabawy: można to zrobić w bardzo ogólny i kompaktowy sposób:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:template match="*">
<xsl:apply-templates select="node()|@*"/>
<xsl:text> </xsl:text>
</xsl:template>
<xsl:template match="username">
at -f <xsl:apply-templates select="*|@*"/>
</xsl:template>
</xsl:stylesheet>
W przypadku zastosowania w tym dokumencie XML :
<script>
<command>
<username>John</username>
<startTime hours="09:" minutes="33"/>
<startDate>05/05/2011</startDate>
<username>Kate</username>
<startTime hours="09:" minutes="33"/>
<startDate>05/05/2011</startDate>
<username>Peter</username>
<startTime hours="09:" minutes="33"/>
<startDate>05/05/2011</startDate>
</command>
</script>
Pożądany, poprawny wynik jest wytwarzany:
at -f 09:33 05/05/2011
at -f 09:33 05/05/2011
at -f 09:33 05/05/2011
Notatka: to podejście genaral jest najlepsze, jeśli wszystkie dane, które mają być wyprowadzone, są zawarte w węzłach tekstowych, a nie w atrybutach.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-06 14:35:56