java 由于 xsl:include 导致转换失败

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/258738/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 11:40:28  来源:igfitidea点击:

Transformation Failing due to xsl:include

javaxslt

提问by will

I have a Java maven project which includes XSLT transformations. I load the stylesheet as follows:

我有一个包含 XSLT 转换的 Java maven 项目。我按如下方式加载样式表:

TransformerFactory tFactory = TransformerFactory.newInstance();

DocumentBuilderFactory dFactory = DocumentBuilderFactory
                .newInstance();

dFactory.setNamespaceAware(true);

DocumentBuilder dBuilder = dFactory.newDocumentBuilder();

ClassLoader cl = this.getClass().getClassLoader();
java.io.InputStream in = cl.getResourceAsStream("xsl/stylesheet.xsl");

InputSource xslInputSource = new InputSource(in);
Document xslDoc = dBuilder.parse(xslInputSource);

DOMSource xslDomSource = new DOMSource(xslDoc);

Transformer transformer = tFactory.newTransformer(xslDomSource);

The stylesheet.xsl has a number of statements. These appear to be causing problems, when I try to run my unit tests I get the following errors:

stylesheet.xsl 有许多语句。这些似乎导致了问题,当我尝试运行单元测试时,出现以下错误:

C:\Code\workspace\app\dummy.xsl; Line #0; Column #0; Had IO Exception with stylesheet file: footer.xsl
C:\Code\workspace\app\dummy.xsl; Line #0; Column #0; Had IO Exception with stylesheet file: topbar.xsl

The include statements in the XSLT are relative links

XSLT 中的 include 语句是相对链接

xsl:include href="footer.xsl"
xsl:include href="topbar.xsl"

I have tried experimenting and changing these to the following - but I still get the error.

我尝试过尝试并将这些更改为以下内容 - 但我仍然收到错误消息。

xsl:include href="xsl/footer.xsl"
xsl:include href="xsl/topbar.xsl"

Any ideas? Any help much appreciated.

有任何想法吗?非常感谢任何帮助。

回答by will

Solved my problem using a URIResolver.

使用 URIResolver 解决了我的问题。

class MyURIResolver implements URIResolver {
@Override
public Source resolve(String href, String base) throws TransformerException {
  try {
    ClassLoader cl = this.getClass().getClassLoader();
    java.io.InputStream in = cl.getResourceAsStream("xsl/" + href);
    InputSource xslInputSource = new InputSource(in);
    Document xslDoc = dBuilder.parse(xslInputSource);
    DOMSource xslDomSource = new DOMSource(xslDoc);
    xslDomSource.setSystemId("xsl/" + href);
    return xslDomSource;
 } catch (...

And assigning this with the TransformerFactory

并将其分配给 TransformerFactory

tFactory.setURIResolver(new MyURIResolver());

回答by Rajdeep Kwatra

URIResolver can also be used in a more straightforward way as below:

URIResolver 也可以以更直接的方式使用,如下所示:

class XsltURIResolver implements URIResolver {

    @Override
    public Source resolve(String href, String base) throws TransformerException {
        try{
              InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("xslts/" + href);
              return new StreamSource(inputStream);
        }
        catch(Exception ex){
            ex.printStackTrace();
            return null;
        }
    }
}

Use the URIResolver with TransformerFactory as shown below:

将 URIResolver 与 TransformerFactory 一起使用,如下所示:

TransformerFactory transFact = TransformerFactory.newInstance();
transFact.setURIResolver(new XsltURIResolver());

Or with a lambda expression:

或者使用 lambda 表达式:

transFact.setURIResolver((href, base) -> {
    final InputStream s = this.getClass().getClassLoader().getResourceAsStream("xslts/" + href);
    return new StreamSource(s);
});

回答by bruno conde

Set your DocumentBuilder object with an EntityResolver.

使用EntityResolver设置您的 DocumentBuilder 对象。

You'll have to extend EntityResolver class to resolve your external entities (footer.xsl and topbar.xsl).

您必须扩展 EntityResolver 类来解析您的外部实体(footer.xsl 和 topbar.xsl)。

回答by matt b

I had a problem similar to this once with relative paths in the XSLT.

我曾经在 XSLT 中遇到过与相对路径类似的问题。

If you can, try to put absolute paths in the XSLT - that should resolve the error.

如果可以,请尝试在 XSLT 中放置绝对路径 - 这应该可以解决错误。

An absolute path probably isn't preferable for the final version of the XSLT, but it should get you past the maven problem. Perhaps you can have two versions of the XSLT, one with absolute paths for maven and one with relative paths for whatever other tool it's being used with.

对于 XSLT 的最终版本来说,绝对路径可能并不可取,但它应该能让您解决 maven 问题。也许您可以拥有两个版本的 XSLT,一个是 maven 的绝对路径,另一个是它正在使用的任何其他工具的相对路径。