如何在 Java 应用程序中使用 XSLT 3.0?

Posted

技术标签:

【中文标题】如何在 Java 应用程序中使用 XSLT 3.0?【英文标题】:How to use XSLT 3.0 from a Java application? 【发布时间】:2017-12-01 11:40:50 【问题描述】:

我用来处理XSLTXML文件的一般java代码是:

public static final String transformXmlDocument(String inputXmlString,
            File xsltFile) 

        TransformerFactory factory = TransformerFactory.newInstance();
        StreamSource xslt = new StreamSource(xsltFile);

        StreamSource text = new StreamSource(new StringReader(inputXmlString));
        StringWriter writer = new StringWriter();
        StreamResult textOP = new StreamResult(writer);

        try 
            Transformer transformer = factory.newTransformer(xslt);
            transformer.transform(text, textOP);
         catch (TransformerConfigurationException e) 
            e.printStackTrace();
         catch (TransformerException e2) 
            e2.printStackTrace();
        
        String results = writer.toString();

        return results;

我必须处理 3.0 版本的 XSLT 才能使用以下功能:

parse-xml-fragment()

这个版本的XSLT 会抛出错误:

parse-xml-fragment() 没有作为函数找到

我的输入 XML :

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<data>
  <![CDATA[<pi>hi</pi>]]>
</data>

XSLT 代码:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     xmlns:xs="http://www.w3.org/2001/XMLSchema"
     xmlns:data="http://example.com/data"
     xmlns:text="http://exselt.net/text"
     xmlns:err="http://www.w3.org/2005/xqt-errors"
     exclude-result-prefixes="xs xsl data text err"
     version="3.0">

<xsl:output indent="yes"/>

     <xsl:template match="/">
         <xsl:variable name="sample">
            <xsl:copy-of select="parse-xml-fragment('&lt;gi&gt;surface&lt;/gi&gt;&lt;gi&gt;surface&lt;/gi&gt;&lt;gi&gt;surface&lt;/gi&gt;')" />
         </xsl:variable>
         <final>
            <xsl:copy-of select="data/pi"/>
             <xsl:for-each select="$sample/gi">
                 <pi><xsl:value-of select="."/></pi>
            </xsl:for-each> 
         </final>
     </xsl:template>

</xsl:stylesheet>

预期输出:

<final>
    <pi>hi</pi>
    <pi>surface</pi>
    <pi>surface</pi>
    <pi>surface</pi>
  </final>

谁能提供解决方案?

【问题讨论】:

【参考方案1】:

您需要确保 Saxon 9.8 HE 或 PE 或 EE 在您的课程路径上,HE 在 Sourceforge 和 Maven 上可用,商业版 PE 和 EE 来自 saxonica.com。请参阅http://saxonica.com/html/documentation/about/installationjava/installingjava.html 和http://saxonica.com/html/documentation/using-xsl/embedding/jaxp-transformation.html,它们建议在安装特定版本后使用例如http://saxonica.com/html/documentation/javadoc/net/sf/saxon/TransformerFactoryImpl.html 直接而不是依赖 JAXP 类加载器机制,所以假设你安装了 Saxon 9.8 HE 可以替换

    TransformerFactory factory = TransformerFactory.newInstance();

    TransformerFactory factory = new net.sf.saxon.TransformerFactoryImpl();

【讨论】:

感谢您的快速响应,我添加了 maven 依赖项: net.sf.saxonSaxon-HE 9.8.0-1 也替换了前面提到的 TransformerFactory 类,但我仍然收到错误,它没有找到 parse-xml-fragment() 作为函数。我错过了什么吗? 请编辑您的问题并显示最小但完整的 XML 输入 sn-ps、XSLT 代码以及允许我们重现问题的确切错误消息。你没有向parse-xml-fragment 传递任何东西吗? 我已经按照先生的要求编辑了问题,当我从命令行运行相同的代码时它可以工作但在 Eclipse 中没有 请花点时间添加最少但完整的 sn-ps,以便我们重现问题。 &lt;xsl:copy-of select"data/pi"/&gt; 甚至不是正确的 XML 语法。而且我认为您发布的 XSLT 没有 36 行。你有没有机会在课程路径上也有其他旧版本的 Saxon? 错误消息:javax.xml.transform.TransformerConfigurationException:编译样式表失败。检测到 1 个错误。在 net.sf.saxon.PreparedStylesheet.prepare(PreparedStylesheet.java:153) 在 net.sf.saxon.TransformerFactoryImpl.newTemplates(TransformerFactoryImpl.java:137) 在 net.sf.saxon.TransformerFactoryImpl.newTransformer(TransformerFactoryImpl.java:88) ) 在 com.translation.xslt.CustomXsltTransformer.transformXmlDocument(CustomXsltTransformer.java:60) 在 com.translationProcessRequest.TestClass.main(TestClass.java:105)

以上是关于如何在 Java 应用程序中使用 XSLT 3.0?的主要内容,如果未能解决你的问题,请参考以下文章

使用 XSLT 3.0 的 JSON 到 XML - 如何加载 JSON 源并调用 json-to-xml 函数?

XSLT 3.0 - 无法在 XSLT 3.0 xml-to-json() 中获取对象数组

XSLT 3.0 - 在 XSLT 3.0 xml-to-json() 中出现错误“重复键值”

如何使用 XSLT 3.0 中的 xsl:stream、xsl:accumulator、xs:fork?

如何修复 XSLT 3.0 地图问题?

Marklogic xml 转换中的 XSLT 3.0 支持