【问题标题】:Java and XSLT: How to specify multiple input files to xslt in java?Java 和 XSLT:如何在 java 中为 xslt 指定多个输入文件?
【发布时间】: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

其中一篇文章提到使用&lt;xsl:param name="f2" as="document-node()"/&gt;,但如何指定多个文件?

更新: 我无法发布答案,所以只需编辑我的问题 -

终于明白了.....

我使用 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");

【问题讨论】:

    标签: java xml xslt saxon


    【解决方案1】:

    堆栈跟踪包含一个 CollectionURIResolver,这意味着您的源代码必须调用 collection() 函数,这在您向我们展示的源代码 sn-p 中没有体现。

    有各种各样的方法来解决这个问题。您可以使用 collection(),也可以传入 URI 列表,也可以传入包含分号分隔或制表符分隔的 URI 序列的单个字符串,以便在样式表中进行标记。

    如果您想将字符串序列作为参数值传递,那么您最好使用 s9api 接口而不是 JAXP。 JAXP 面向 XSLT 1.0,它没有字符串列表作为可识别的数据类型。

    您展示的 XSLT 片段非常奇怪,它从作为输入传递的一组元素的乘数属性创建一组称为“乘数”的属性;这与您向我们展示的 JAXP 调用序列中的任何内容无关。

    【讨论】:

      猜你喜欢
      • 2017-05-10
      • 2013-01-07
      • 2011-08-01
      • 1970-01-01
      • 2010-11-10
      • 1970-01-01
      • 2018-11-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多