2009-02-01 30 views
5

Domanda

Abbiamo un gran numero di file di configurazione XML che vogliamo fusi in un unico versione principale in fase di compilazione. I file di configurazione più piccoli sono più facili da mantenere e un file di grandi dimensioni si carica più velocemente, quindi ho immaginato che si trattasse di un processo di trasformazione build popolare che avrei trovato molti buoni esempi di rete.concatenare dinamicamente i file XML con formica e XSLT

Sono stato in grado di trovare alcune buone soluzioni per una parte del problema here at StackOverflow ma tutti si basano sulla conoscenza dei nomi dei file xml che devono essere uniti. Questo mi sembra un inutile sovraccarico. Dovrebbe essere possibile scrivere uno script di compilazione che possa calcolare in modo dinamico i file di input xml necessari.

Sfortunatamente, l'unico modo per ottenere questo risultato era un po 'un trucco. Funziona così,

  1. Utilizzare un compito di formica casuale che ho rubato su Internet per scrivere un elenco di directory in un file xml.
  2. Alimenta il file xml in una trasformazione xslt che può quindi caricare l'altra directory che elenca i file xml di riferimento e concatenarli.
  3. Elimina il file xml temporaneo che contiene l'elenco di directory.

Ecco lo script ant

<taskdef name="xml-dir-list" 
    classname="net.matthaynes.xml.dirlist.AntFileListing" 
    classpath="antlib/xml-dir-listing.0.1.jar; 
    antlib/jakarta-regexp-1.5.jar;antlib/log4j-1.2.14.jar"/> 

<macrodef name="build-plugin-xml" description="todo"> 
    <attribute name="pluginName"/> 

    <xml-dir-list depth="0" verbose="false" 
     srcDir="${src.dir}/@{pluginName}/forms/" includesRegEx="\.xml$" 
     destFile="${src.dir}/@{pluginName}/forms/fileList.xml"/> 

    <xslt in="${src.dir}/forms/fileList.xml" 
     out="${src.dir}/@{pluginName}/@{pluginName}_extn.yuix 
     style="${src.dir}/@{pluginName}/forms/extn.yuix.xsl" /> 

    <delete file="${src.dir}/@{pluginName}/forms/fileList.xml"/> 
</macrodef> 

Ed ecco il foglio di stile,

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 

    <xsl:template match="/"> 
     <Forms applicationId="YFSSYS00011"> 
      <GlobalExtensions> 
       <Tasks/> 
      </GlobalExtensions> 
      <xsl:apply-templates select="directory/file"/> 
     </Forms> 
    </xsl:template> 

    <xsl:template match="file"> 
     <xsl:copy-of select="document(@name)/Forms/Form"/> 
    </xsl:template> 
</xsl:stylesheet> 

Qualcuno ha trovato un modo più semplice per raggiungere questa scoperta dinamica dei quali file di fondere in XSLT? Non sorprende che XSLT non sia in grado di leggere le directory direttamente, ma speravo di trovare un modo più semplice per passare un elenco di nomi di file piuttosto che attraverso un altro file xml.

implementato la soluzione

Dimitre's solution funzionava benissimo una volta avevo fatto un paio di modifiche in più per lo script formica,

<taskdef name="saxon-xslt" classname="net.sf.saxon.ant.AntTransform" 
    classpath="antlib/saxon9.jar;antlib/saxon9-ant.jar"/> 

[...]

<macrodef name="build-plugin-xml" description="todo"> 
    <attribute name="pluginName"/> 

    <saxon-xslt 
     in="build.xml" 
     out="${compca.src.dir}/temp/@{pluginName}/@{pluginName}_extn.yuix" 
     style="antscripts/extn.yuix.xsl"> 
    <param name="formsDir" 
     expression="${compca.src.dir}/@{pluginName}/forms/"/> 
    </saxon-xslt> 
</macrodef> 

e il foglio di stile XSL (che ho spostato)

<xsl:stylesheet version="1.0" 
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
     <xsl:param name="formsDir" /> 
     <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 

     <xsl:template match="/"> 
      <Forms applicationId="YFSSYS00011"> 
       <GlobalExtensions> 
        <Tasks/> 
       </GlobalExtensions> 
       <xsl:apply-templates select= 
        "collection(
        concat('file:///', 
        $formsDir, 
        '?select=*.yuix;recurse=yes;on-error=ignore' 
       ) 
       )/* 
       "/> 
      </Forms> 

     </xsl:template> 

     <xsl:template match="file"> 
      <xsl:copy-of select="/Forms/Form"/> 
     </xsl:template> 
    </xsl:stylesheet> 

Quei ritocchi erano proprio intorno al caricamento di Saxon9 e all'impostazione della directory con un parametro.

risposta

6

Qualcuno ha trovato un modo più semplice per raggiungere questa scoperta dinamica di ciò che file per unire in XSLT? Non è sorprendente che XSLT non è in grado di leggere direttamente le directory , ma speravo che trovasse un modo più semplice per passare un elenco di nomi di file piuttosto che tramite un altro file xml.

scoperta dinamica e l'elaborazione dei file XML possono essere fatto utilizzando XPath 2/0/XSLT 2.0. Più in particolare, è necessario utilizzare la funzione XPath 2.0 collection().

Per dettagli, vedere my answer to this question.

Quindi, se ANT può utilizzare un adeguato processore XSLT 2.0, (mi consiglia di utilizzare Saxon), il problema ha una soluzione completa, utilizzando la funzione standard collection().

Problemi correlati