Domanda

Ho un foglio di stile XSLT esistente che prende XML e produce XHTML ben formattato. Voglio fare una versione XSL-FO di questo foglio di stile per la produzione di PDF via Apache FOP. Quello che voglio sapere è questo:

Ci sono dei comodi da usare modelli XSLT ho bisogno di imparare a fare le cose come:

  • copia di alcuni nodi inalterato
  • la copia di più di un nodo, ma l'aggiunta di attributi extra

So di poter creare nuovi nodi utilizzando

<xsl:element>

, ma ci sono altre cose utili che avrà bisogno. Si noti che mentre io non ho fatto un sacco di copiare da un formato ad un altro XSLT, ho tonnellate fatta di XML> XHTML via XSLT quindi sono familiarità con la maggior parte del nucleo del linguaggio.

È stato utile?

Soluzione

Il modello che stai cercando è l ' "identità modificata trasformare". La base di questo approccio è la regola dell'identità trasformerà, la prima regola modello nel foglio di stile in basso. Ogni regola dopo che rappresenta un'eccezione al comportamento di copia.

<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <!-- By default, copy all nodes unchanged -->
  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

  <!-- But strip out <foo> elements (including their content) -->
  <xsl:template match="foo"/>

  <!-- For <bar> elements, strip out start & end tags, but leave content --> 
  <xsl:template match="bar">
    <xsl:apply-templates/>
  </xsl:template>

  <!-- For <bat> elements, insert an attribute and append a child --> 
  <xsl:template match="bat">
    <xsl:copy>
      <xsl:apply-templates select="@*"/>
      <xsl:attribute name="id">123</xsl:attribute>
      <xsl:apply-templates/>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

Da almeno soddisfacente per me di quanto sopra è la duplicazione della logica trovata in ultima regola modello. Questo è un sacco di codice per solo l'aggiunta di un attributo. E immaginate se abbiamo bisogno di un po 'di questi. Ecco un altro approccio che ci permette di essere più chirurgicamente preciso in quello che vogliamo ignorare:

<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <!-- By default, copy all nodes unchanged -->
  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@*"/>
      <xsl:apply-templates mode="add-atts" select="."/>
      <xsl:apply-templates/>
    </xsl:copy>
  </xsl:template>

          <!-- By default, don't add any attributes -->
          <xsl:template mode="add-atts" match="*"/>

  <!-- For <bat> elements, insert an "id" attribute -->
  <xsl:template mode="add-atts" match="bat">
    <xsl:attribute name="id">123</xsl:attribute>
  </xsl:template>

</xsl:stylesheet>

Infine, questo può essere effettuato molto più in là, con una modalità diversa per ogni tipo di modifica che si potrebbe desiderare di fare:

<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <!-- For <bat> elements, insert an "id" attribute -->
  <xsl:template mode="add-atts" match="bat">
    <xsl:attribute name="id">123</xsl:attribute>
  </xsl:template>

  <!-- Append <new-element/> to <bat> -->
  <xsl:template mode="append" match="bat">
    <new-element/>
  </xsl:template>

  <!-- Insert an element in <foo> content -->
  <xsl:template mode="insert" match="foo">
    <inserted/>
  </xsl:template>

  <!-- Add content before the <bar/> and <bat/> elements -->
  <xsl:template mode="before" match="bar | bat">
    <before-bat-and-bar/>
  </xsl:template>

  <!-- Add content only after <bat/> -->
  <xsl:template mode="after" match="bat">
    <after-bat/>
  </xsl:template>

  <!-- Here's the boilerplate code -->
  <!-- By default, copy all nodes unchanged -->
  <xsl:template match="@* | node()">
    <xsl:apply-templates mode="before" select="."/>
    <xsl:copy>
      <xsl:apply-templates select="@*"/>
      <xsl:apply-templates mode="add-atts" select="."/>
      <xsl:apply-templates mode="insert" select="."/>
      <xsl:apply-templates/>
      <xsl:apply-templates mode="append" select="."/>
    </xsl:copy>
    <xsl:apply-templates mode="after" select="."/>
  </xsl:template>

          <!-- By default, don't add anything -->
          <xsl:template mode="add-atts" match="*"/>
          <xsl:template mode="insert"   match="*"/>
          <xsl:template mode="append"   match="*"/>
          <xsl:template mode="before"   match="@* | node()"/>
          <xsl:template mode="after"    match="@* | node()"/>

</xsl:stylesheet>

In XSLT 2.0, alcuni dei boilerplate può essere leggermente semplificata, grazie a regole di modello multi-mode:

          <!-- By default, don't add anything -->
          <xsl:template mode="add-atts
                              insert
                              append
                              before
                              after" match="@* | node()"/>

a volte io uso tutti questi modi personalizzati nello stesso foglio di stile, ma più spesso di quanto non li aggiungo pigramente -. Se necessario

Altri suggerimenti

Il più grande ostacolo alla trasformazione XSLT è che il prefisso di uscita namespace è la stessa di quella delle istruzioni XSL effettivi nel trasformare. Se si utilizza “xsl:” sia nelle istruzioni XSL e la vostra uscita, il motore XSLT non conoscere la differenza tra le istruzioni XSL dovrebbe eseguire e chi si dovrebbe uscita, così il vostro XSLT non analizzare. Cioè, a meno che non si utilizza un alias namespace:

<xsl:namespace-alias stylesheet-prefix="x" result-prefix="xsl"/>

Questa istruzione, che è collocato all'interno di <xsl:stylesheet />, permette di scrivere il vostro codice risultato nella vostra trasformazione utilizzando un prefisso namespace sostituto. Più tardi, quando viene creato il documento di output, il prefisso che si vuole realmente verrà inserito al posto del alias. Così, per esempio, ecco un modello che produce un modello nel documento di output:

<xsl:template match="xsl:template[@match='title']>
   <x:template match="title>
      <x:apply-templates />
   </x:template>
</xsl:template>

Ecco un buon articolo: http: //www.xml .com / pub / a / 2001/04/04 / trxml /

In passato ho sviluppato fogli di stile XSL-FO e poi utilizzato il Render-X FO2HTML foglio di stile per convertire il XSL-FO in HTML. Converte elementi <block> in <div>, <inline> in <span>, ecc.

Non li ho usato prima, ma si potrebbe prendere in considerazione cercando HTML2FO fogli di stile . O almeno guardando oltre a prendere in prestito alcune idee.

Dato che HTML che manca alcuni dei impaginazione costrutti che FO fornisce non si potrebbe dare tutto quello che vi serve per l'output XSL-FO, ma probabilmente potrebbe gestire la maggior parte della logica di conversione da HTML a elemento XSL-FO / attributi nel corpo del documento.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top