【问题标题】:Transformation Failing due to xsl:include由于 xsl:include 导致转换失败
【发布时间】:2010-09-20 11:59:32
【问题描述】:

我有一个包含 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);

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

XSLT 中的 include 语句是相对链接

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

我已经尝试过试验并将其更改为以下内容 - 但我仍然收到错误。

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

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

【问题讨论】:

    标签: java xslt


    【解决方案1】:

    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;
            }
        }
    }
    

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

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

    或者使用 lambda 表达式:

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

    【讨论】:

      【解决方案2】:

      使用 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 (...
      

      并将其分配给 TransformerFactory

      tFactory.setURIResolver(new MyURIResolver());
      

      【讨论】:

      • 别忘了设置documentBuilderFactory.setNamespaceAware(true)。否则可能会阻止父样式表加载子样式表中的任何模板,从而导致 ElemTemplateElement 错误。
      • 注意,setURIResolver 也可以在transformer上设置(即代替工厂),但是没有效果。
      【解决方案3】:

      使用EntityResolver 设置您的 DocumentBuilder 对象。

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

      【讨论】:

        【解决方案4】:

        我曾经在 XSLT 中遇到过与此类似的问题。

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

        绝对路径可能不适用于 XSLT 的最终版本,但它应该可以帮助您解决 maven 问题。也许您可以拥有两个版本的 XSLT,一个带有 maven 的绝对路径,一个带有用于它所使用的任何其他工具的相对路径。

        【讨论】:

        • 马特,感谢您的回复 - 这确实解决了问题。但是,样式表包含在 jar 文件中,因此一旦将整个内容打包,此解决方案将无法正常工作。
        猜你喜欢
        • 2021-01-18
        • 1970-01-01
        • 1970-01-01
        • 2015-11-09
        • 2014-12-05
        • 2018-04-22
        • 2014-06-29
        • 2016-10-10
        • 2015-09-04
        相关资源
        最近更新 更多