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ì,
- Utilizzare un compito di formica casuale che ho rubato su Internet per scrivere un elenco di directory in un file xml.
- Alimenta il file xml in una trasformazione xslt che può quindi caricare l'altra directory che elenca i file xml di riferimento e concatenarli.
- 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.