usar o xsl para enviar texto simples

precisava de usar o XSL para gerar uma saída de texto simples a partir do XML. Uma vez que eu não encontrei nenhum bom, exemplo conciso on-line, eu decidi postar minha solução aqui. Quaisquer ligações que se refiram a um exemplo melhor seriam naturalmente apreciadas:

<?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>
Algumas coisas importantes que me ajudaram aqui:
  1. a utilização de xsl: resultado para omitir a declaração-padrão no início do documento de saída
  2. a utilização do atributo xml: space= "preserve" para preservar qualquer espaço em branco que escrevi dentro do xsl: para-cada tag. Isso também me obrigou a escrever todo o código dentro da marca para-cada, incluindo essa marca também, em uma única linha (com exceção da quebra de linha).
  3. o uso de inserir uma quebra de linha novamente eu tive que omitir indenting xml padrão aqui.

a saída resultante e desejada para este xslt foi:

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

Como eu disse, Qualquer sugestão de como fazer isto de forma mais elegante seria apreciada.


SEGUIMENTO 2011-05-08:

Aqui está o tipo de xml que estou a tratar.
<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>
Author: Chris, 2011-05-06

2 answers

  • você pode definir um modelo para corresponder a script/command e eliminar o xsl:for-each
  • concat() pode ser usado para encurtar a expressão e salvá-lo de inserir explicitamente tantos elementos <xsl:text> e <xsl:value-of>.
  • o uso de uma referência de entidade &#xA; para o retorno do transporte, em vez de depender de preservar a quebra de linha entre o seu elemento <xsl:text> é um pouco mais seguro, uma vez que a formatação de código não vai estragar as suas quebras de linha. Além disso, para mim, lê-se como uma quebra de linha explícita e é é mais fácil compreender a intenção.

<?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>
 22
Author: Mads Hansen, 2011-05-06 11:26:38

Apenas por Diversão: isso pode ser feito de uma forma muito geral e compacta:

<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>

Quando aplicado neste documento 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>

O resultado desejado e correto é produzido:

   at -f 09:33 05/05/2011 
   at -f 09:33 05/05/2011 
   at -f 09:33 05/05/2011  

Nota : esta abordagem genaral é melhor aplicável se todos os dados a serem obtidos estiverem contidos nos nós de texto -- não nos atributos.

 7
Author: Dimitre Novatchev, 2011-05-06 14:35:56