Использовать xsl для вывода простого текста
Мне нужно было использовать XSL для создания простого текстового вывода из XML. Поскольку я не нашел ни одного хорошего, краткого примера в Интернете, я решил опубликовать свое решение здесь. Разумеется, любые ссылки, ссылающиеся на лучший пример, будут оценены:
<?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>
Несколько важных вещей, которые помогли мне здесь:
- использование xsl: output для исключения стандартного объявления в начале выходного документа
- использование атрибута xml: space = "сохранить" для сохранения любых пробелов, которые я написал в теге xsl: for-each. Это также потребовало, чтобы я написал весь код внутри каждого тега, включая этот тег, в одной строке (за исключением разрыва строки).
- использование вставки разрыва строки - снова мне пришлось опустить стандартный отступ xml здесь.
Полученный и желаемый результат для этого xslt был:
at -f alluser 23:58 17.4.2010
на -f ggroup67 7:58 28.4.2010
at -f ggroup70 15:58 18.4.2010
at -f alluser 23:58 18.4.2010
на -f ggroup61 7:58 22.9.2010
на -f ggroup60 23:58 21.9.2010
на -f alluser 3:58 22.9.2010
Как я уже сказал, любые предложения о том, как сделать это более элегантно, будут оценены.
ПОСЛЕДУЮЩАЯ ДЕЯТЕЛЬНОСТЬ 2011-05-08:
Вот тип xml, который я рассматриваю:
<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>
Ответы
Ответ 1
- Вы можете определить шаблон для соответствия на
script/command
и устранить xsl:for-each
-
concat()
можно использовать, чтобы сократить выражение и избавить вас от явной вставки стольких элементов <xsl:text>
и <xsl:value-of>
.
- Использование ссылки на объект


для возврата каретки вместо того, чтобы полагаться на сохранение разрыва строки между вашим элементом <xsl:text>
, является более безопасным, поскольку форматирование кода не испортит ваши разрывы строк. Кроме того, для меня он читается как явный разрыв строки и легче понять намерение.
<?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>
Ответ 2
Просто для удовольствия: это можно сделать очень общим и компактным способом:
<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>
при применении к этому 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>
выдается желаемый, правильный результат:
at -f 09:33 05/05/2011
at -f 09:33 05/05/2011
at -f 09:33 05/05/2011
Примечание. Этот генный подход лучше всего применим, если все данные, которые будут выводиться, содержатся в текстовых узлах, а не в атрибутах.