Dynamically concatenate xml files with ant and xslt

Question

We have a large number of xml configuration files that we want to merge into one major version at build time. Smaller configuration files are easier to maintain, and one large file downloads faster, so I imagined it was a popular build conversion process and I would find many good examples on the net.

I was able to find some good solutions for one part of the problem https://stackoverflow.com/a/16626716/237327 , but they all rely on knowing the names of the XML files that need to be joined together. This seems like an unnecessary overhead for me. It should be possible to write an assembly script that can dynamically calculate which input XML files are needed.

Unfortunately, the only way I could find for this is to hack a bit. It works as follows:

  • Use the random ant task that I stole on the Internet to write a list of directories to an xml file.
  • Submit the XML file to an xslt conversion, which can then load another directory that contains links to xml files and combine them.
  • Delete the temporary xml file containing the list of directories.

Here ant script

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

And here is the stylesheet,

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

Has anyone found an easier way to achieve this dynamic detection of which files are merged into XSLT? Unsurprisingly, XSLT cannot directly read directories, but I was hoping to find an easier way to pass a list of file names than through another XML file.

Implemented solution

Dimitre , ant script,

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

xsl ( )

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

Saxon9 .

+5
1

- , XSLT? , XSLT , , XML .

XML XPath 2/0/XSLT 2.0. , XPath 2.0 collection().

. .

, ANT XSLT 2.0, ( Saxon), , collection().

+6

All Articles