在XSLT中调用Java实例方法

时间:2012-10-06 16:48:49

标签: java xslt saxon

我正在使用Saxon(我可以在必要时使用Xalan)XSLT处理器进行一些转换。 我想将下面对象的实例作为参数传递给XSLT模板。

public class Test {
   private String value;

   public Test(String v) {
       value = v;
   }
   //getters, setters etc.
}

所以我创建了这个对象,即

Test test = new Test("test");
transformer.setParameter("test", test);

在XSLT文件中,我将param声明为:

<xsl:param name="test" required="yes" as="jt:com.whatever.package.Test" xmlns:jt="http://saxon.sf.net/java-type"/>

现在我的问题是如何在XSLT中对此对象调用任何实例方法(即getValue())?它甚至可能吗?我知道我可以调用不同Java类的静态方法,但这并不是我想要的。

此外,是否可以在XSLT中填充Java对象,即。调用setter方法作为对象的实例,然后在转换完成后将此对象与Java代码中的新值一起使用?

4 个答案:

答案 0 :(得分:5)

您应该能够以您描述的方式调用作为参数传入的“外部对象”的实例方法。如果$ object是这样的对象,并且com.package.MyClass是它的类,并且你想在这个对象上调用方法getColor,那么

(a)你需要声明一个名称空间,例如xmlns:MyClass =“java:com.package.MyClass”

(b)将该方法称为MyClass:getColor($ object)

这种调用Java的机制在Saxon中被称为“反身扩展函数”。 Saxon Home Edition不支持它。您将需要Saxon专业版或旧的开源Saxon-B产品。 Saxon-HE中还有另一种称为“集成扩展函数”的机制,但它需要在Java端进行更多编码来声明参数和结果的类型。

您需要注意,对于反射扩展函数,Saxon正在对如何将Java类型映射到XPath类型做出最好的猜测,并且它并不总是以您希望的方式进行映射,尤其是在使用集合时类型。

尽量避免使用带副作用的方法,例如setter方法。在Saxon中没有绝对可靠的方法确保此类调用以任何特定顺序执行,有时Saxon优化器将找到一种组织查询的方法,以避免进行调用。如果您必须进行此类调用,请将它们视为调用返回结果(例如空序列),并以这样的方式使用调用:如果它确实返回结果,则结果将显示在样式表输出中。< / p>

答案 1 :(得分:3)

此处已详细说明

http://www.saxonica.com/html/documentation/extensibility/functions/

简短示例

<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:date="java:java.util.Date" exclude-result-prefixes="date">

<xsl:template match="/">
  <html>
    <xsl:if test="function-available('date:to-string') and
                          function-available('date:new')">
      <p><xsl:value-of select="date:to-string(date:new())"/></p>
    </xsl:if>
  </html>
</xsl:template>

</xsl:stylesheet>

应用于任何XML文档(未使用)时会生成所需的正确结果:

<html>
   <p>Sat Oct 06 11:41:30 PDT 2012</p>
</html>

答案 2 :(得分:1)

我很久以前就用Xalan做过这个。首先,您需要将以下内容添加到xslt中(我认为您不需要放置所有其他属性)

<xsl:param name="test" />

然后,要调用该方法,您可以执行

<xsl:value-of select="test:getValue()"/>

答案 3 :(得分:0)

我发布的时间已经太晚,但对于其他人而言,这可能会有所帮助。

您可以在xalan处理器的帮助下轻松实现这一目标:

步骤1:包括Xalan依赖或涉及的合适的jar

<!-- https://mvnrepository.com/artifact/xalan/xalan -->
 <dependency>
<groupId>xalan</groupId>
<artifactId>xalan</artifactId>
<version>2.7.1</version>
</dependency>

步骤2.在与java

集成时选择此处理器
TransformerFactory factory = TransformerFactory.newInstance("org.apache.xalan.processor.TransformerFactoryImpl",null);

步骤3.在xsl中输入样式表中的信息

xmlns:uuid="xalan://PackageName.className"

请注意,此类应具有您将在xslt

中使用的Static方法

第4步:在xslt中使用它

<xsl:value-of select="uuid:methodName(string(xpath))" />

它可以是字符串或数字..取决于您的方法参数

来源:http://www.cafeconleche.org/books/xmljava/chapters/ch17s03.html