【问题标题】:Error when calling java static method from xslt从 xslt 调用 java 静态方法时出错
【发布时间】:2015-11-19 09:15:39
【问题描述】:

我正在尝试从 XSLT 调用静态 java 代码。我的 XSLT 文件如下所示

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns1="interface.dev"
exclude-result-prefixes="ns1"
 xmlns:xltxe="http://www.ibm.com/xmlns/prod/xltxe-j"
 xmlns:countryCode="http://com.abc/common/utils">

<xltxe:java-extension prefix="countryCode" class="com.abc.common.utils.CountryStaticInfo"/>

<xsl:variable name="var" select="ns1:parties/ns1:party[@code='BNE']/ns1:country"/>

<xsl:template match="/ns1:import_lc_iss">
  <html>
  <body>
    <table border="1">
        <tr>
  <xsl:value-of select="countryCode:getCountryCode($var)" />
      </tr>
      </table>
      </body>
      </html>
    </xsl:template>

</xsl:stylesheet>

我的 Java 代码如下所示:

public synchronized static String getCountryCode(String aS_ctryCode) throws Exception, StaticInfoException {

    ArrayList lAL_entities = com.abc.services.JavaProgramContext.getServerEntities();
    return getCountryCode(lAL_entities.get(0).toString(),aS_ctryCode);
}

我收到以下错误

RROR: '非静态 Java 函数的第一个参数 “getCountryCode”不是有效的对象引用。
46860 [main] 错误 - 无法通过 xslt 转换收到的消息 javax.xml.transform.TransformerConfigurationException:无法编译样式表 在 com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl.newTemplates(TransformerFactoryImpl.java:828) 在 com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl.newTransformer(TransformerFactoryImpl.java:617)

第 1 次修正:支持 xalan 的新 xslt

    <xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:ns1="interface.dev"
    exclude-result-prefixes="ns1"
     xmlns:xalan="http://xml.apache.org/xalan"
     extension-element-prefixes="xalan" 
      xmlns:java="java"
      xmlns:util="com.abc.common.utils.CountryStaticInfo">

    <xltxe:java-extension prefix="countryCode" class="com.abc.common.utils.CountryStaticInfo"/>

 <xsl:variable name="var" select="AU"/>   
    <xsl:template match="/ns1:import_lc_iss">
      <html>
      <body>
        <table border="1">
            <tr>
      <xsl:variable name="new-pop"     select="com.abc.common.utils.CountryStaticInfo.getCountryCode(string(@var))"/>
          </tr>
          </table>
          </body>
          </html>
        </xsl:template>

    </xsl:stylesheet>

【问题讨论】:

  • 好吧,com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl 建议您使用内置于 Sun/Oracle JRE 中的 Xalan 实现,我认为命名空间 http://www.ibm.com/xmlns/prod/xltxe-j 中的扩展元素 xltxe:java-extension 对 Xalan 没有任何意义。请参阅有关扩展 xml.apache.org/xalan-j/extensions.html 的 Xalan 文档。
  • 谢谢马丁,你是对的,但仍然如此。没有设法调用 Java 静态方法。查看问题的修正
  • 如果我理解文档,那么一种方法是在 XSLT 样式表中声明命名空间 xmlns:java="http://xml.apache.org/xalan/java",然后您可以使用例如调用静态 Java 方法select="java:com.abc.common.utils.CountryStaticInfo.getCountryCode('foo')"。这是我首先要尝试的,确保可以使用静态值调用该方法,然后,如果可行,我会尝试传入从 XML 中选择的值。

标签: java xml xslt


【解决方案1】:

下面是http://xml.apache.org/xalan-j/extensions.html#ext-functions 中的文档和示例之后的示例,它适用于 Oracle JRE 8,XSLT 是

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

    <xsl:output method="html"/>

    <xsl:template match="/">
        <html>
            <head>
                <title>sheet1.xsl</title>
            </head>
            <body>
                <xsl:apply-templates/>
            </body>
        </html>
    </xsl:template>

    <xsl:template match="country-list">
        <ul>
            <xsl:apply-templates/>
        </ul>
    </xsl:template>

    <xsl:template match="country">
        <li>
            <xsl:value-of select="java:org.example.MyClass.getCountryCode(.)"/>
        </li>
    </xsl:template>

</xsl:stylesheet>

Java 类库在包org.example 中有

package org.example;

import java.util.HashMap;
import java.util.Map;

public class MyClass {

    private static final Map<String, String> COUNTRY_LIST = new HashMap<>();

    static {
        COUNTRY_LIST.put("Spain", "es");
        COUNTRY_LIST.put("USA", "us");
    }

    public static String getCountryCode(String name) {
        return COUNTRY_LIST.get(name);
    }
}

然后 JRE 中的内置 Transformer 可以很好地转换此示例。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-08-31
    • 2018-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-02
    • 2014-07-28
    相关资源
    最近更新 更多