我有一组xml文件(每个文件都有不同的结构,它们的编号可能会有所不同),我需要将它们组合成一个xml文件。
我生成了一个xslt文件(使用MapForce),它将多个xml文件作为输入。以下代码段显示了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");
答案 0 :(得分:1)
堆栈跟踪包含一个CollectionURIResolver,这意味着您的源代码必须调用collection()函数,这在您向我们展示的源代码片段中没有证据。
有各种各样的方法可以解决这个问题。您可以使用collection(),也可以传入URI列表,也可以传入包含以分号分隔或以制表符分隔的URI序列的单个字符串,以便在样式表中进行标记。
如果要将一系列字符串作为参数值传递,那么最好使用s9api接口而不是JAXP。 JAXP面向XSLT 1.0,它没有一个字符串列表作为公认的数据类型。
您展示的XSLT片段非常奇怪,它创建了一组名为&#34;乘数&#34;从作为输入传递的一组元素的乘数属性;这与你向我们展示的JAXP调用序列中的任何内容都没有关系。