这是情况。转换的输出必须基于文件集中文件的数字和名称。文件集看起来像这样:
<fileset dir="lpf-version-34.0/" casesensitive="yes">
<include name="*/*-uniques.xml"/>
</fileset>
假设我在此文件集中有三个文件:
lpf-version-34.0/1/tod-uniques.xml
lpf-version-34.0/2/tod-uniques.xml
lpf-version-34.0/3/tod-uniques.xml
我希望以某种方式将这些文件传递(例如参数)到xsl
文件,因此我可以这样产生这样的输出:
<files>
<file path="lpf-version-34.0/1/tod-uniques.xml"/>
<file path="lpf-version-34.0/2/tod-uniques.xml"/>
<file path="lpf-version-34.0/3/tod-uniques.xml"/>
</files>
您可以使用PathConvert任务来限制文件集的所有文件并将其存储到属性中。之后,您可以将该属性作为参数传递到XSL样式表并在XSL中处理。在一个构建参数传递给XSL的示例下方:
<fileset dir="lpf-version-34.0/" casesensitive="yes" id="lpf-files.id">
<include name="*/*-uniques.xml"/>
</fileset>
<pathconvert pathsep="," property="lpflist" refid="lpf-files.id"/>
<xslt in="somefile.xml" style="style.xsl" out="result.xml">
<param name="files" expression="${lpflist}"/>
</xslt>
当然,它假定您的XSL文件(该示例中的style.xsl)定义并正确处理参数files
。
在以下解决方案中:
- ANT的
<script>
任务使用JavaScript从<fileset>
生成XML。 - XML作为字符串参数传递给XSLT样式表。
- Saxon-B
saxon:parse
功能将XML字符串转换为适当的XML节点。 - XSLT样式表将XML节点插入新的XML文档。
Saxon-B是一个XSLT处理器,具有方便的功能,名为Saxon:Parse:
[Saxon:Parse]采用一个参数,一个包含形式良好XML文档的源文本的字符串。它返回文档节点(根节点),该节点是由解析此文本而产生的。
要使用saxon-b,请从http://saxon.sourceforge.net/下载saxonb9-1-0-8j.zip。用build.xml文件从下载的zip文件中提取saxon9.jar。
in.xml
<?xml version="1.0"?>
<theRoot/>
build.xml
<project name="ant-xslt-call-with-xml-param" default="run" basedir=".">
<target name="run">
<!-- The fileset needs an "id" so the JavaScript can find it. -->
<!-- -->
<!-- Note: "dir" was "lpf-version-34.0" in the question. -->
<!-- The JavaScript is simpler with "lpf-version-34.0" in the <include>. -->
<fileset id="my-fileset" dir="${basedir}" casesensitive="yes">
<include name="lpf-version-34.0/*/*-uniques.xml"/>
</fileset>
<script language="javascript">
<![CDATA[
// A bunch of XML infrastructure boilerplate.
var docFactory = javax.xml.parsers.DocumentBuilderFactory.newInstance();
var docBuilder = docFactory.newDocumentBuilder();
var tFactory = javax.xml.transform.TransformerFactory.newInstance();
var transformer = tFactory.newTransformer();
transformer.setOutputProperty(
javax.xml.transform.OutputKeys.OMIT_XML_DECLARATION, "yes");
var writer = new java.io.StringWriter();
var doc = docBuilder.newDocument();
var filesElement = doc.createElement("files");
doc.appendChild(filesElement);
var fileSet = project.getReference( "my-fileset" );
var ds = fileSet.getDirectoryScanner( project );
var includes = ds.getIncludedFiles();
for ( var i = 0; i < includes.length; i++ )
{
var filename = includes[i]
var singleFileElement = doc.createElement("file");
singleFileElement.appendChild(doc.createTextNode(filename));
filesElement.appendChild(singleFileElement);
}
transformer.transform(
new javax.xml.transform.dom.DOMSource(doc),
new javax.xml.transform.stream.StreamResult(writer));
var outputXml = writer.getBuffer().toString();
project.setProperty( "fileset-xml", outputXml );
]]>
</script>
<xslt style="transform.xsl" in="in.xml" out="out.xml">
<classpath location="saxon9.jar"/>
<factory name="net.sf.saxon.TransformerFactoryImpl"/>
<param name="fileset-xml" expression="${fileset-xml}"/>
</xslt>
</target>
</project>
transform.xsl
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:saxon="http://saxon.sf.net/"
>
<xsl:output method="xml" indent="yes" />
<xsl:param name="fileset-xml"/>
<xsl:template match="/theRoot">
<xsl:copy>
<xsl:copy-of select="saxon:parse($fileset-xml)"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
结果XML
<?xml version="1.0" encoding="UTF-8"?>
<theRoot>
<files>
<file>lpf-version-34.01tod-uniques.xml</file>
<file>lpf-version-34.02tod-uniques.xml</file>
<file>lpf-version-34.03tod-uniques.xml</file>
</files>
</theRoot>