【发布时间】:2014-09-15 06:36:27
【问题描述】:
我有一组 xml 文件(每个都有不同的结构,它们的数量可能会有所不同),我需要将它们组合成一个 xml 文件。
我生成了一个 xslt 文件(使用 MapForce),它以多个 xml 文件作为输入。以下 sn -p 显示了 xslt 文件的输入 -
<xsl:param name="input" select="()"/>
<xsl:for-each select="$input/@multiplier">
<xsl:attribute name="multiplier" select="fn:string(.)"/>
</xsl:for-each>
<xsl:sequence select="fn:string($input)"/>
我正在使用 s9API 将我的输入转换为所需的输出 xml 文件 -
InputStream stylesheetInputStream = new FileInputStream("xsltFile.xslt");
StreamSource input = new StreamSource(new FileInputStream("input.xml"));
StreamResult output = new StreamResult(new FileOutputStream("output.xml"));
TransformerFactory factory = net.sf.saxon.TransformerFactoryImpl.newInstance();
Transformer t = factory.newTransformer(new StreamSource(stylesheetInputStream));
t.setParameter("input", new File[]{new File("source_1.xml"), new File("source_2.xml"), new File("source_3.xml")});
t.transform(input, output);
我不断收到异常,由于某种原因,实际上是错误中提到的输出文件,这很奇怪(当然,这个文件是空的) -
Error on line 1 column 1 of output.xml:
SXXP0003: Error reported by XML parser: Premature end of file.
; SystemID: ; Line#: 90; Column#: -1
net.sf.saxon.trans.XPathException: org.xml.sax.SAXParseException: Premature end of file.
at net.sf.saxon.event.Sender.sendSAXSource(Sender.java:425)
at net.sf.saxon.event.Sender.send(Sender.java:178)
at net.sf.saxon.Configuration.buildDocument(Configuration.java:3516)
at net.sf.saxon.lib.StandardCollectionURIResolver$FileExpander.map(StandardCollectionURIResolver.java:441)
at net.sf.saxon.lib.StandardCollectionURIResolver$FileExpander.map(StandardCollectionURIResolver.java:321)
at net.sf.saxon.expr.MappingIterator.next(MappingIterator.java:56)
at net.sf.saxon.expr.ItemMappingIterator.next(ItemMappingIterator.java:83)
at net.sf.saxon.expr.ContextMappingIterator.next(ContextMappingIterator.java:52)
at net.sf.saxon.value.SequenceExtent.<init>(SequenceExtent.java:105)
at net.sf.saxon.expr.sort.DocumentOrderIterator.<init>(DocumentOrderIterator.java:31)
at net.sf.saxon.expr.sort.DocumentSorter.iterate(DocumentSorter.java:101)
at net.sf.saxon.expr.instruct.ForEach.processLeavingTail(ForEach.java:414)
at net.sf.saxon.expr.instruct.Block.processLeavingTail(Block.java:615)
at net.sf.saxon.expr.instruct.Instruction.process(Instruction.java:131)
at net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:301)
at net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:254)
at net.sf.saxon.expr.instruct.Instruction.process(Instruction.java:131)
at net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:301)
at net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:254)
at net.sf.saxon.expr.instruct.Block.processLeavingTail(Block.java:615)
at net.sf.saxon.expr.instruct.Instruction.process(Instruction.java:131)
at net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:301)
at net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:254)
at net.sf.saxon.expr.LetExpression.processLeavingTail(LetExpression.java:586)
at net.sf.saxon.expr.instruct.Template.applyLeavingTail(Template.java:212)
at net.sf.saxon.trans.Mode.applyTemplates(Mode.java:1034)
at net.sf.saxon.Controller.transformDocument(Controller.java:1957)
at net.sf.saxon.Controller.transform(Controller.java:1803)
at com.test.Transform.performTransform(Transform.java:33)
at com.test.Transform.main(Transform.java:15)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:90)
我的 xslt 文件是否正确指定输入?如果不是,如何指定多个文件作为输入? 还是我在代码中错误地设置了参数?
我在这里找到了一个相关的查询 - Transformation of multiple input files
其中一篇文章提到使用<xsl:param name="f2" as="document-node()"/>,但如何指定多个文件?
更新: 我无法发布答案,所以只需编辑我的问题 -
终于明白了.....
我使用 MapForce 并且对 xslt 不是很熟悉,所以我无法过多解释下面的表达式,但从概念上讲我是这样做的 -
我使用逗号分隔的字符串(包含文件列表)作为输入,然后对其进行标记。
<xsl:param name="listOfFiles" as="xs:string" required="yes"/>
<xsl:for-each select="tokenize($listOfFiles, replace(',', '(\.|\$|\^|\{|\[|\(|\||\)|\*|\+|\?|\\)', '\\$1'))">
对于我的 java 代码 -
t.setParameter("listOfFiles", "file1.xml,file2.xml");
【问题讨论】: