【问题标题】:How can I call a method on a Java instance passed into XSLT?如何调用传入 XSLT 的 Java 实例的方法?
【发布时间】:2017-02-17 20:58:41
【问题描述】:

我需要让 XSLT 调用我作为参数传递的 Java 实例上的方法。到目前为止,如果我在 XSLT 本身中创建实例,我只能让它工作。如果我尝试在传递的实例上调用它,则会失败

Exception in thread "main" javax.xml.transform.TransformerConfigurationException: 
Cannot find external method 'Test.get' (must be public).

我可以通过输出它来证明实例传递正常(它以 toString 的形式出现)。这是我的 Java:

public class Test {

    public static void main(String[] args) throws Exception {
        Transformer transformer = TransformerFactory.newInstance()
            .newTransformer(
            new StreamSource(Test.class.getResourceAsStream("test.xsl")));
        transformer.setParameter("test1", new Test());
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        transformer.transform(new StreamSource(
            new ByteArrayInputStream(
            "<?xml version=\"1.0\"?><data></data>".getBytes())),
            new StreamResult(outputStream));
        System.out.println(outputStream.toString());
    }

    public String get() {
        return "hello";
    }

    @Override
    public String toString() {
        return "An instance of Test";
    }
}

这是我的 xsl:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:test="xalan://Test"
                exclude-result-prefixes="test"
>

    <xsl:param name="test1" />
    <xsl:variable name="test2" select="$test1"/>
    <xsl:variable name="test3" select="test:new()"/>

    <xsl:template match="/">
        <data>
            <!-- proves that the instance is really being passed -->
            <xsl:value-of select="$test1"/>
        </data>
        <data>
            <!-- first two do not work -->
            <!--<xsl:value-of select="test:get($test1)"/>-->
            <!--<xsl:value-of select="test:get($test2)"/>-->
            <!-- this one does work -->
            <xsl:value-of select="test:get($test3)"/>
        </data>
    </xsl:template>
</xsl:stylesheet>

有谁知道我如何使用传递的参数来完成这项工作?在 XSLT 中实例化它在我的实际用例中不起作用。谢谢。

【问题讨论】:

  • 您需要说明您使用的是什么 XSLT 处理器。 JAXP API 没有定义任何从 XSLT 调用 Java 的机制,而且实现 JAXP API 的不同处理器之间的约定也有所不同。
  • @Michael Kay 我正在使用 Java 8,它似乎正在使用 Xalan
  • 那么抱歉,Xalan 帮不上忙。

标签: java xml xslt


【解决方案1】:

为了让这条线正常工作:

<xsl:value-of select="test:get($test1)"/>

参数可以传递给静态函数:

class Test {

  public static void get(Object context) {
     // here "context" is the instance "test1"
  }
...

【讨论】:

  • 这是我发现在 Xalan 中调用实例方法的唯一方法。奇怪的是它没有被赞成。虽然它需要包装以使用 Object 参数定位 java 方法,但它可以工作并且包装并不是什么大问题。
【解决方案2】:

我也遇到了同样的问题。检查后发现我们需要使用下面的依赖项

        <dependency>
            <groupId>xalan</groupId>
            <artifactId>serializer</artifactId>
            <version>2.7.2</version>
        </dependency>
        
        
        <dependency>
            <groupId>xalan</groupId>
            <artifactId>xalan</artifactId>
            <version>2.7.2</version>
        </dependency>

添加这些依赖项后,我的代码开始工作了。

【讨论】:

    猜你喜欢
    • 2012-09-27
    • 1970-01-01
    • 2011-03-27
    • 1970-01-01
    • 2021-08-03
    • 1970-01-01
    • 1970-01-01
    • 2013-10-01
    • 2014-11-21
    相关资源
    最近更新 更多