首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将XML文件(InputStream)传递给XSLT避免在XSLT javax.xml中使用文档

将XML文件(InputStream)传递给XSLT避免在XSLT javax.xml中使用文档
EN

Stack Overflow用户
提问于 2014-10-01 21:17:34
回答 2查看 3.9K关注 0票数 3

我对XML、XSLT和javax.xml还不熟悉。

目前,我的目标是使用XSLTVersion1.0合并两个XML文件,一切正常。

但是我觉得我的代码中有一个限制,如果可能的话,我想消除它。

以下是我的资源:“file1.xml”、file2.xml“merge.xslt”

这是我的合并方法:

代码语言:javascript
复制
public ByteArrayOutputStream merge(final InputStream file1) {
    final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    final TransformerFactory tFactory = TransformerFactory.newInstance();
    Transformer transformer;
    try {
        transformer = tFactory.newTransformer(new StreamSource("merge.xslt"));
        transformer.transform(new StreamSource(file1), new StreamResult(outputStream));
    } catch (final TransformerConfigurationException e) {
        LOG.warn("Problem occurred transforming files configuration issue", e);
    } catch (final TransformerException e) {
        LOG.warn("Problem occurred transforming files", e);
    }
    return outputStream;
}

--这是我在XSLT中传递file2.xml的方式

代码语言:javascript
复制
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:param name="lookup" select="document('/file2.xml')"/>

<xsl:template match="/">
  Do the processing how I want
</xsl:template>
</xsl:stylesheet>

我想实现的是,我想修改我的合并方法,以传递file1.xml和file2.xml。

代码语言:javascript
复制
public ByteArrayOutputStream merge(final InputStream file1,final InputStream file2)

我想以某种方式将这个InputStream file2传递给XSLT,这样就消除了从文件系统读取文件的限制。

能不能有人指点我,如果可能的话,如何做到这一点,我真的很感激大家的帮助。

谢谢。

我尝试了一个很小的例子,这里提到了XSLT Processing with Java : passing xml content in parameter,但是它对我没有用。

代码语言:javascript
复制
final InputStream file1 = new FileInputStream("file1.xml");
    final InputStream file2 = new FileInputStream("file2.xml");
    final TransformerFactory tFactory = TransformerFactory.newInstance();
    Transformer transformer;
    transformer = tFactory.newTransformer(new StreamSource("merge.xslt"));
    transformer.setParameter("lookup", new StreamSource(file2));
    transformer.transform(new StreamSource(file1), new StreamResult(new FileOutputStream("test.xml")));

并将XSLT更新如下:

代码语言:javascript
复制
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:param name="lookup"/>

<xsl:template match="/">
  Do the processing how I want
</xsl:template>
</xsl:stylesheet>

我正在收到的错误如下:

代码语言:javascript
复制
ERROR:  'Invalid conversion from 'javax.xml.transform.stream.StreamSource' to 'node-set'.'
Exception in thread "main" javax.xml.transform.TransformerException: java.lang.RuntimeException: Invalid conversion from 'javax.xml.transform.stream.StreamSource' to 'node-set'.
at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:755)
at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:359)

还使用:

代码语言:javascript
复制
<xsl:param name="lookup"/>

我是否可以访问XSLT中的file2.xml。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-10-03 03:19:53

经过大量的研究和阅读不同的帖子和博客,我终于解决了我的问题。

我参考了这里提出的问题,并提出了这样做的想法。

Pass document as parameter to XSL Translation in Java

这个帖子中提出的其他解决方案并没有对我产生影响。

我就是这么做的

使用URIResolver而不是参数。

代码语言:javascript
复制
public class DocumentURIResolver implements URIResolver {

final Map<String, Document> _documents;

public DocumentURIResolver(final Map<String, Document> documents) {
    _documents = documents;
}

public Source resolve(final String href, final String base) {
    final Document doc = _documents.get(href);
    return (doc != null) ? new DOMSource(doc) : null;
    }
}

我就是这样修改我的方法的:

代码语言:javascript
复制
public ByteArrayOutputStream merge(final InputStream file1,final InputStream file2) {
final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
final TransformerFactory tFactory = TransformerFactory.newInstance();
Transformer transformer;
try {
    transformer = tFactory.newTransformer(new StreamSource("merge.xslt"));
    final DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
    final Document documentFile = db.parse(file2);
    Map<String, Document> docs = new HashMap<String, Document>();
    docs.put("lookup", documentFile);
    transformer.setURIResolver(new DocURIResolver(docs));
    transformer.transform(new StreamSource(file1), new StreamResult(outputStream));
} catch (final TransformerConfigurationException e) {
    LOG.warn("Problem occurred transforming files configuration issue", e);
} catch (final TransformerException e) {
    LOG.warn("Problem occurred transforming files", e);
}
return outputStream;
}

这就是我在XSLT中引用它的方式:

代码语言:javascript
复制
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:variable name="lookup" select="document('documentFile')"/>

<xsl:template match="/">
  Do the processing how you want to
</xsl:template>
</xsl:stylesheet>
票数 3
EN

Stack Overflow用户

发布于 2014-10-01 22:18:24

由于不希望在XSLT中使用document()函数,所以可以使用Java中的DOM函数合并输入文件。

代码语言:javascript
复制
DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document merge = db.newDocument();
Element root = merge.createElement("root");
merge.appendChild(root);
Document d1 = db.parse(new File("file1.xml"));
Document d2 = db.parse(new File("file2.xml"));
root.appendChild(merge.importNode(d1.getDocumentElement(), true));
root.appendChild(merge.importNode(d2.getDocumentElement(), true));

然后,如果需要,可以将合并的文档传递给XSLT。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26150821

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档