代码之家  ›  专栏  ›  技术社区  ›  jjanczur

内存中具有外部函数(functx)的XSLT

  •  2
  • jjanczur  · 技术社区  · 7 年前

    我遇到了一个问题。我需要在中使用XSLT 2.0(SAXON-HE 9.8.0处理器)转换XML Java语言

    当两个文件(xslt映射和带有functx的.xsl文件)都是 在同一目录中 每件事 .

    xmlns:functx=”http://www.functx.com"

    xsl:import href=“functx-package.xsl”

    有没有办法 使用外部功能 来自我的functx。xsl映射时间 两个文件 在内存中作为字符串 对象或输入流或其他?

    我无法像以前那样将驱动器上的文件存储在一个目录中。

    唯一可能解决我的问题的方法是将functx文件粘贴到我的。xsl映射器,但这是错误的解决方案-[非常]糟糕的做法。

    我使用什么:

    • SAXON-HE 9.8.0处理器
    • XSLT 2.0
    2 回复  |  直到 7 年前
        1
  •  3
  •   Michael Kay    7 年前

    为编译时URIResolver提供逻辑

    public Source resolve(String href, String base) {
      if (href.equals("functx-package.xsl")) {
         return new StreamSource(new StringReader(functxAsString));
      } else {
         return null;
      }
    }
    

    如果您使用s9api,编译时URIResolver是提供给XsltCompiler的,如果您使用JAXP,则是提供给TransformerFactory的。

        2
  •  0
  •   jjanczur    7 年前

    综上所述:

    import documentation from Saxon

    要正确使用此解析器,我们需要 在TransformerFactory中设置 . 然后每个transformer将在导入中捕获href并将文件与我们的匹配。xsl文件作为字符串。我还使用outputURIResolver捕捉输出并在内存中创建多个文件。(outputURIResolver的有趣用法- link )

    例子:

    在里面xsl文件:

    <xsl:import href="functx-package.xsl"/>
    <xsl:import href="functs-package.xsl"/>
    

    在java中:

       TransformerFactory tFactory = TransformerFactory.newInstance("net.sf.saxon.TransformerFactoryImpl", XMLviaXSLTransformer.class.getClassLoader());
    
        tFactory.setURIResolver(new URIResolver() {
            @Override
            public Source resolve(String href, String base) {
                if (href.equals("functx-package.xsl")) {
                    return new StreamSource(new StringReader(finalFunctsAsString));
                } else if (href.equals("functs-package.xsl")) {
                    return new StreamSource(new StringReader(finalFunctxAsString));
                } else {
                    return null;
                }
            }
        });
    
        Transformer transformer = tFactory.newTransformer(xsltMap);
        StreamResult standardResult = new StreamResult(new ByteArrayOutputStream());
        transformer.transform(xmlInput, standardResult);
    

    谢谢你,迈克尔。这个URIResolver非常强大。