2012-10-06 88 views
4

我正在使用Saxon(如果需要,我可以使用Xalan)XSLT处理器进行一些转换。 我想将以下对象的实例作为参数传递给XSLT模板。在XSLT中调用Java实例方法

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文件我宣布帕拉姆为:

<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代码中使用这个对象和新值?

+0

你使用哪种版本撒克逊的是什么呢? –

+0

我正在使用Saxon 9.谢谢 – Zyga

+0

“确切”在这里至关重要。例如,Saxon-B 9.1的答案与Saxon-HE 9.4的答案不同。 –

回答

3

你应该能够调用通过了“外部对象”的实例方法作为你描述的参数。如果$ object是这样一个对象,并且com.package.MyClass是它的类,并且您想调用此对象的getColor方法,那么需要声明一个名称空间,如xmlns:MyClass = “java的:com.package.MyClass”

(b)中调用方法MyClass的:的getColor($对象)

此机制用于调出到Java在撒克逊称为“自反扩展函数”。它在Saxon Home Edition中不受支持。您将需要撒克逊专业版或旧的开源Saxon-B产品。 Saxon中还有另一种称为“集成扩展函数”的机制,但它需要在Java方面多一点编码来声明参数和结果的类型。

您需要注意的是,使用自反扩展功能,撒克逊对如何将Java类型映射到XPath类型做出了最好的猜测,并且它并不总是以您想要的方式进行映射,特别是在使用集合类型。

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

1

我很久以前用Xalan做了这个。首先,您需要将以下添加到您的XSLT(我不认为你需要的一切,你把其他属性)

<xsl:param name="test" /> 

,然后调用的方法,你可以做

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

它不与撒克逊工作(说未声明的命名空间前缀{测试})。我会安装Xalan并尝试它。撒克逊人首选,因为它支持xslt2。谢谢 – Zyga

+0

我试图用Xalan做到这一点,但它表示'名称空间前缀'测试'未声明'。 – Grief

2

这是彻底这里解释说:

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> 
+0

+1和OP的说明:您还可以将'extension-element-prefixes ='date''添加到'xsl:stylesheet'中,这样您就不会得到'xmlns:date =“java:java.util。日期“在输出中。 –

+1

虽然扩展元素前缀会产生这种效果,但这是该作业的错误工具:要使用的正确属性是exclude-result-prefixes。 –

0

它太迟了我发布,但对于其他人可能会有所帮助。

步骤1::

可以容易地与处理器的Xalan的帮助下实现此包括的Xalan依赖性或合适的罐涉案

<!-- 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

步骤4的静态方法:在XSLT使用它

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

它可以是字符串或数字。 .depending在你的方法参数

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

+0

问题是关于实例方法,而不是静态方法 – Grief