Подтвердить что ты не робот

Использовать 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>
4b9b3361

Ответ 1

  • Вы можете определить шаблон для соответствия на script/command и устранить xsl:for-each
  • concat() можно использовать, чтобы сократить выражение и избавить вас от явной вставки стольких элементов <xsl:text> и <xsl:value-of>.
  • Использование ссылки на объект &#xA; для возврата каретки вместо того, чтобы полагаться на сохранение разрыва строки между вашим элементом <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
                    ,'&#xA;')"/>
    </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  

Примечание. Этот генный подход лучше всего применим, если все данные, которые будут выводиться, содержатся в текстовых узлах, а не в атрибутах.