используйте xsl для вывода простого текста - PullRequest
28 голосов
/ 06 мая 2011

Мне нужно было использовать 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>

Несколько важных вещей, которые мне здесь помогли:

  1. использование xsl: output, чтобы опуститьстандартное объявление в начале выходного документа
  2. использование атрибута xml: space = "preserve" для сохранения любых пропусков, которые я написал в теге xsl: for-each.Это также потребовало, чтобы я написал весь код внутри тега for-each, включая этот тег, в одну строку (за исключением разрыва строки).
  3. использование для вставки переноса строки - снова я должен был опустить здесь стандартный отступ XML.

Полученный и желаемый результат для этого xslt был:

at -f alluser 23:58 17.4.2010at -f ggroup67 7:58 28.4.2010at -f ggroup70 15:58 18.4.2010at -f alluser 23:58 18.4.2010at -f ggroup61 7:58 22.9.2010at -f ggroup60 23:58 21.9.2010at -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>

Ответы [ 2 ]

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

Просто для удовольствия: это можно сделать очень общим и компактным способом :

<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  

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

...