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

将XML文件(InputStream)传递给XSLT避免使用XSLT javax.XML中的文档,java,xml,xslt,javax.xml,Java,Xml,Xslt,Javax.xml,我不熟悉XML、XSLT和javax.XML 目前,我的目标是使用XSLT 1.0版合并两个XML文件,一切正常 但是我觉得我的代码中有一个限制,如果可能的话,我想去掉它。 这些是我的资源: “file1.xml” “file2.xml” “merge.xslt” 这是我的合并方法: public ByteArrayOutputStream merge(final InputStream file1) { final ByteArrayOutputStream outputStream

我不熟悉XML、XSLT和javax.XML

目前,我的目标是使用XSLT 1.0版合并两个XML文件,一切正常

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

这些是我的资源: “file1.xml” “file2.xml” “merge.xslt”

这是我的合并方法:

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的方式

<?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>
我想以某种方式将这个InputStream文件2传递给XSLT,这样就消除了从文件系统读取文件的限制

如果有人能指导我这是可能的,以及如何实现它,我将非常感谢所有的帮助

多谢各位

我尝试了一个小例子,这里提到 但这对我不起作用

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更新如下:

<?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>
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)
还使用:

<xsl:param name="lookup"/>


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

因为您不想在XSLT中使用document()函数,所以可以使用Java中的DOM函数合并输入文件

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。

在做了大量研究并阅读了不同的帖子和博客之后,我终于能够解决我的问题

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

这篇文章中建议的其他解决方案对我来说并不合适

这就是我所做的

使用了
URIResolver
而不是参数

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;
    }
}
公共类DocumentURIResolver实现URIResolver{
最终地图文件;
公共文档解析程序(最终地图文档){
_文件=文件;
}
公共源解析(最终字符串href,最终字符串基){
最终文档doc=\u documents.get(href);
返回(doc!=null)?新建DOMSource(doc):null;
}
}
我就是这样修改我的方法的:

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;
}
public ByteArrayOutputStream合并(最终InputStream文件1,最终InputStream文件2){
final ByteArrayOutputStream outputStream=新建ByteArrayOutputStream();
final TransformerFactory tFactory=TransformerFactory.newInstance();
变压器;
试一试{
transformer=tFactory.newTransformer(新的StreamSource(“merge.xslt”);
final DocumentBuilder db=DocumentBuilderFactory.newInstance().newDocumentBuilder();
最终文件documentFile=db.parse(文件2);
Map docs=newhashmap();
文档放置(“查找”,文档文件);
transformer.setURIResolver(新的DocURIResolver(docs));
transform(新的StreamSource(file1),新的StreamResult(outputStream));
}捕获(最终转换器配置异常e){
LOG.warn(“转换文件配置问题出现问题”,e);
}捕获(最终转换异常e){
LOG.warn(“转换文件时出现问题”,e);
}
返回输出流;
}
这就是我在XSLT中对它的评价:

<?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>

按照您想要的方式进行处理

使用XSLT,除了使用document()读取的文档外,只能有一个输入文档。您可以将文件名传递给document命令。或者,您也可以使用DOM解析器解析文档,并使用importNode函数将每个文档导入主输出文档。@terrywb我对所有这些都不熟悉,因此我实际上很困惑,不理解您试图指导的内容。实际上,我希望避免在xslt中使用文档读取file2.xml。我想做的是将file2.xml作为参数传递给java代码中的XSLT,并读取它以比较要合并的处理逻辑。我的实现目前正在运行。但我希望避免从文件系统读取,并将该文件保存在一些InputStream中。我不知道如何在java中传递这些信息,并在XSLT中阅读这些信息?我不相信不使用document()函数就可以在XSLT中实现您想要的功能。请参阅下面我的解决方案,使用代码将输入文档合并在一起。您可能需要定义一个Java
UriResolver
。定义后,当系统必须解析
文档()
引用时,它将作为触发器调用。在这一点上,你可以简单地传递你包含文档的任何输入流。@MarcusRickert你能给我看一个关于你指导的示例代码吗,我实际上不太明白你试图在哪里指导我,谢谢。我明白你试图指导我的意思。但是我不想合并这两个文档并使用XSLT对它们进行过滤。我还编辑了这个问题,因为我正在尝试测试在线寻找解决方案的功能。我认为这是可能的,但我不知道怎么做。我得到的错误我已经添加到问题中。你有这方面的经验吗?如果你看到我对这个问题的编辑,也许会有所帮助。我还联系了另一个问题。@terrywd我发布了解决方案,我能够解决它。
<?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>