2009-02-01 5 views
5

Вопрос

У нас есть большое количество конфигурационных файлов XML, которые мы хотим слиты в одну эталонную версию во время сборки. Меньшие конфигурационные файлы проще в обслуживании, а один большой файл загружается быстрее, поэтому я представлял себе, что это популярный процесс преобразования сборки, и я найду много хороших примеров в сети.динамически конкатенация XML-файлы с муравьиной и XSLT

Я смог найти некоторые полезные решения для одной части проблемы here at StackOverflow, но все они полагаются на знание имен файлов xml, которые необходимо объединить спереди. Это кажется ненужным накладным для меня. Должно быть возможно написать скрипт сборки, который может динамически вычислять, какие входные XML-файлы необходимы.

К сожалению, единственный способ, который я смог найти для этого, - это немного взломать. Он работает следующим образом:

  1. Используйте случайную задачу муравья, которую я украл в Интернете, чтобы написать список каталогов в xml-файл.
  2. Загрузите XML-файл в преобразование xslt, которое затем может загрузить другой каталог, на котором указаны ссылки на файлы xml, и объединить их.
  3. Удалить временный файл xml, содержащий список каталогов.

Вот муравей скрипт

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

А вот таблица стилей,

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

Кто-нибудь нашел более простой способ добиться этого динамического обнаружения того, что файлы для слияния в XSLT? Неудивительно, что XSLT не может напрямую читать каталоги, но я надеялся найти более простой способ передать список имен файлов, чем через другой XML-файл.

Реализовано решение

Dimitre's solution работал большой, как только я сделал несколько дополнительных настроек для муравьев сценарий,

<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: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 и установки каталога с параметром.

ответ

6

Кто-нибудь нашел более простой способ достижения этой динамическое обнаружение того, что файлы для слияния в XSLT? Это не удивительно, что XSLT не умеет читать каталогов напрямую, но я надеялся , чтобы найти более простой способ перечислить список имен файлов, чем через еще один XML-файл.

Динамическое обнаружение и обработка XML-файлов может быть сделано с помощью XPath 2/0/XSLT 2.0. В частности, нужно использовать функцию XPath 2.0 collection().

Подробнее см. my answer to this question.

Таким образом, если АНТ может использовать подходящий процессор XSLT 2.0, (я бы рекомендовал использовать Saxon), задача имеет полное решение, используя стандартную функцию collection().