如何只使用Ant和XSLT创建目标目录中的文件列表的XML文件?

时间:2021-01-08 15:01:51

Using only Ant and XSLT, I'd like to create an XML file that is a list of XML files in a specific directory.

只使用Ant和XSLT,我想创建一个XML文件,它是特定目录中的XML文件列表。

Ant's concat task doesn't do the job as I end up with a list that's not XML -- ie. it doesn't have a single root element.

Ant的concat任务不能完成这个任务,因为我最后得到的不是XML的列表。它没有一个根元素。

I have an XSLT file that I apply, using the XSLT Ant task, that uses the collection() function. This produces exactly the result I want, but it tries to do so for each file in the target directory -- I want just one list. My XSLT is operating on every file in the target directory (collection) -- how can I limit the number of tims the XSLT is applied?

我使用XSLT Ant任务应用了一个XSLT文件,该文件使用collection()函数。这将生成我想要的结果,但它试图对目标目录中的每个文件都这样做——我只想要一个列表。我的XSLT在目标目录(集合)中的每个文件上运行,如何限制XSLT应用的tims的数量?

Here's what I have so far:

这是我目前所拥有的:

XML files are in the target directory c:\tmp

XML文件位于目标目录c:\tmp中

This is the XSL file that I apply to the files in the target directory (using the Ant XSLT task);

这是我应用到目标目录中的文件的XSL文件(使用Ant XSLT任务);

 <xsl:template match="/">
    <xsl:call-template name="generatelist" />
</xsl:template>

<xsl:template name="generatelist">
    <xsl:result-document href="list.xml">
        <xsl:element name="list">
            <xsl:element name="dir">
                <xsl:for-each
                    select="collection('file:///C:/tmp?select=*.xml')">
                    <xsl:element name="file">
                        <xsl:attribute name="name">
                            <xsl:value-of select="tokenize(document-uri(.), '/')[last()]" />
                        </xsl:attribute>
                    </xsl:element>
                </xsl:for-each>
            </xsl:element>
        </xsl:element>
    </xsl:result-document>
</xsl:template>

And this is the resulting XML list:

这是得到的XML列表:

<list>
    <dir>
        <file name="filename_1.xml"/>
        <file name="filename_2.xml"/>
         . . .
        <file name="filename_n.xml"/>
    </dir>
</list>

Thanks.

谢谢。

Drew

画了

Adding the Ant XSLT task that I'm using:

添加我正在使用的Ant XSLT任务:

<xslt basedir="${staging_2}"
      destdir="${staging_3}" extension=".xml" includes="**/*.xml"
      style="create_list.xsl">     
</xslt>

2 个解决方案

#1


1  

Since the XSLT itself takes care of enumerating the file names you just need to run it once, i.e. give it just one file to use as input and one file to use as output. The stylesheet doesn't use anything from the input document so any input file will do as long as it's XML, you could use the stylesheet itself as its own input.

由于XSLT本身负责枚举文件名,所以只需要运行一次,也就是说,只需要为它提供一个文件作为输入,一个文件作为输出。样式表不使用输入文档中的任何内容,因此只要输入文件是XML,就可以使用样式表本身作为输入。

<xslt style="create_list.xsl" in="create_list.xsl" out="list.xsl" />

and remove the <xsl:result-document> from the stylesheet so it just outputs to the default result document (the one specified by out="..." in build.xml).

并从样式表中删除 ,使其只输出到默认的结果文档(在build.xml中,out="…"指定的文档)。

#2


3  

XSLT really isn't the appropriate tool for your needs. XSLT is best for transforming XML into new XML. In this case, however, the source isn't XML; it's a filesystem directory.

XSLT确实不适合您的需要。XSLT最好将XML转换为新的XML。然而,在这种情况下,源不是XML;这是一个文件系统目录。

Given this, it's fine to just generate the XML directly. The following Ant script uses the third-party Ant-Contrib library's <for> task:

因此,直接生成XML是可以的。下面的Ant脚本使用第三方Ant-后悔库的 任务:

<project name="ant-echo-xml" default="run" basedir=".">
    <taskdef resource="net/sf/antcontrib/antlib.xml" />

    <target name="run">
        <property name="dest-xml.file" value="list.xml"/>

        <echo file="${dest-xml.file}"
><![CDATA[<list>
    <dir>
]]></echo>

        <for param="src-xml.absolute-path">
            <fileset dir="my-dir" includes="*.xml"/>
            <sequential>
                <local name="src-xml.basename"/>
                <basename property="src-xml.basename" file="@{src-xml.absolute-path}"/>

                <echo file="${dest-xml.file}" append="yes"
>        <![CDATA[<file name="${src-xml.basename}"/>
]]></echo>
            </sequential>
        </for>

        <echo file="${dest-xml.file}" append="yes"
><![CDATA[    </dir>
</list>
]]></echo>
    </target>
</project>

Outputs:

输出:

<list>
    <dir>
        <file name="filename_1.xml"/>
        <file name="filename_2.xml"/>
    </dir>
</list>

#1


1  

Since the XSLT itself takes care of enumerating the file names you just need to run it once, i.e. give it just one file to use as input and one file to use as output. The stylesheet doesn't use anything from the input document so any input file will do as long as it's XML, you could use the stylesheet itself as its own input.

由于XSLT本身负责枚举文件名,所以只需要运行一次,也就是说,只需要为它提供一个文件作为输入,一个文件作为输出。样式表不使用输入文档中的任何内容,因此只要输入文件是XML,就可以使用样式表本身作为输入。

<xslt style="create_list.xsl" in="create_list.xsl" out="list.xsl" />

and remove the <xsl:result-document> from the stylesheet so it just outputs to the default result document (the one specified by out="..." in build.xml).

并从样式表中删除 ,使其只输出到默认的结果文档(在build.xml中,out="…"指定的文档)。

#2


3  

XSLT really isn't the appropriate tool for your needs. XSLT is best for transforming XML into new XML. In this case, however, the source isn't XML; it's a filesystem directory.

XSLT确实不适合您的需要。XSLT最好将XML转换为新的XML。然而,在这种情况下,源不是XML;这是一个文件系统目录。

Given this, it's fine to just generate the XML directly. The following Ant script uses the third-party Ant-Contrib library's <for> task:

因此,直接生成XML是可以的。下面的Ant脚本使用第三方Ant-后悔库的 任务:

<project name="ant-echo-xml" default="run" basedir=".">
    <taskdef resource="net/sf/antcontrib/antlib.xml" />

    <target name="run">
        <property name="dest-xml.file" value="list.xml"/>

        <echo file="${dest-xml.file}"
><![CDATA[<list>
    <dir>
]]></echo>

        <for param="src-xml.absolute-path">
            <fileset dir="my-dir" includes="*.xml"/>
            <sequential>
                <local name="src-xml.basename"/>
                <basename property="src-xml.basename" file="@{src-xml.absolute-path}"/>

                <echo file="${dest-xml.file}" append="yes"
>        <![CDATA[<file name="${src-xml.basename}"/>
]]></echo>
            </sequential>
        </for>

        <echo file="${dest-xml.file}" append="yes"
><![CDATA[    </dir>
</list>
]]></echo>
    </target>
</project>

Outputs:

输出:

<list>
    <dir>
        <file name="filename_1.xml"/>
        <file name="filename_2.xml"/>
    </dir>
</list>