XSLT 1.0升级至2.0后Java扩展函数调用失败问题
将XSLT从1.0版本升级至2.0版本后,原有的Java扩展函数无法正常运行,出现两类错误:
Oxygen编辑器报错
找不到名为Q{http://www.oracle.com/XSL/Transform/java/sunil.classic.aib.userfunctions.CustomExtensionFunctions}getSecondaryLineItems()的4参数函数。如需诊断Java方法调用问题,请使用-TJ命令行选项或设置Configuration属性FeatureKeys.TRACE_EXTERNAL_FUNCTIONS
Eclipse运行Java代码报错
XML-23002: (错误)内部xpath错误:
oracle.xml.parser.v2.XMLParseException; lineNumber: 2; columnNumber:1; 预期根元素开始。
at oracle.xml.parser.v2.XMLError.flushErrors1(XMLError.java:326)
at oracle.xml.parser.v2.NonValidatingParser.parseRootElement(NonValidatingParser.java:475)
at oracle.xml.parser.v2.NonValidatingParser.parseDocument(NonValidatingParser.java:416)
at oracle.xml.parser.v2.XMLParser.parse(XMLParser.java:247)
at oracle.xml.jaxp.JXDocumentBuilder.parse(JXDocumentBuilder.java:175)
at oracle.xml.jaxp.JXDocumentBuilder.parse(JXDocumentBuilder.java:131)
at com.bt.classic.provide.Provide.xmlBuild(Provide.java:71)
at com.bt.classic.provide.Provide.main(Provide.java:44)
相关XSLT代码片段
<?xml version="1.0" encoding="UTF-8" ?> <?oracle-xsl-mapper <!-- SPECIFICATION OF MAP SOURCES AND TARGETS, DO NOT MODIFY. --> <mapSources> <source type="XSD"> <schema location="BTOrderEntryReqResp.xsd"/> <rootElement name="ListOfBtorderentryreqigbl" namespace="http://www.siebel.com/xml/BTOrderEntryIGBL"/> </source> </mapSources> <mapTargets> <target type="XSD"> <schema location="GlobalInteraction_Inter.xsd"/> <rootElement name="BatchLoadOrder" namespace="GlobalInteraction.xsdobjects.extload.services.classic.bt.inter"/> </target> </mapTargets> <!-- GENERATED BY ORACLE XSL MAPPER 10.1.3.3.0(build 070615.0525) AT [FRI AUG 10 16:02:57 IST 2012]. --> ?> <xsl:stylesheet version="2.0" xmlns:xp20="http://www.oracle.com/XSL/Transform/java/oracle.tip.pc.services.functions.Xpath20" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:sunil="http://www.oracle.com/XSL/Transform/java/sunil.classic.aib.userfunctions.CustomExtensionFunctions" exclude-result-prefixes="xp20 xsl"> <tns:ActivationDate> <xsl:value-of select="xp20:current-dateTime()"/> </tns:ActivationDate> ................................. <!-- 升级XSLT到2.0后此处代码出现问题,sunil:getSecondaryLineItems为Java文件中的函数 --> <xsl:variable name="SecondaryLineItems" select="sunil:getSecondaryLineItems($totalLineItems,$lineItemsWithoutRW,$lineItemsWithRW,$rootelement)"/> <!-- 针对BW110776的修改 --> <xsl:variable name="PrimaryLineItems" select="sunil:getPrimaryLineItems($totalLineItems,$SecondaryLineItems[not(wiz:Product='IP Connect global SLA')],$rootelement2)"/> ....................... </xsl:stylesheet>
问题核心:升级XSLT到2.0版本后,sunil:getSecondaryLineItems等Java扩展函数调用失败。
针对两类错误分别处理:
一、Oxygen中"找不到4参数函数"的问题
XSLT 2.0对Java扩展函数的参数类型匹配要求远严于1.0版本的宽松匹配规则:
- 校验Java方法签名:确认
CustomExtensionFunctions类中getSecondaryLineItems方法的参数类型,与XSLT中传入的$totalLineItems、$lineItemsWithoutRW、$lineItemsWithRW、$rootelement的类型完全一致。- 例如XSLT 1.0会自动转换节点集到
Node,但XSLT 2.0中节点集对应的是NodeList或Iterable<Node>类型,需确保Java方法参数类型匹配。
- 例如XSLT 1.0会自动转换节点集到
- 启用跟踪排查:按照提示添加
-TJ命令行参数,或在代码中设置FeatureKeys.TRACE_EXTERNAL_FUNCTIONS为true,查看实际传递的参数类型及方法查找过程,定位类型不匹配的具体位置。 - 核对命名空间绑定:确认
sunil命名空间的URI是否正确指向Java类的全限定名,无拼写错误。
二、Eclipse中XML解析"预期根元素开始"的问题
该错误是XML解析器在处理XSLT文件时,发现内容违反XML结构规范导致:
- 修复Oracle XSL Mapper处理指令:
<?oracle-xsl-mapper ...?>处理指令内部包含未转义的XML标签,破坏了XML文档结构。可选择:- 将处理指令内的XML标签进行转义(如把
<替换为<,>替换为>); - 若不需要该mapper元数据,直接删除整个
<?oracle-xsl-mapper ...?>处理指令。
- 将处理指令内的XML标签进行转义(如把
- 验证XSLT文件合法性:使用XML校验工具检查XSLT文件是否符合XML语法规范,确保无未闭合标签、非法字符等问题。
额外注意事项
- Oracle XSLT 2.0处理器(如XDK)对扩展函数的支持逻辑与1.0版本差异较大,建议参考官方文档确认XSLT 2.0扩展函数的调用规则。
- 若使用Saxon等其他XSLT 2.0处理器,Java扩展函数的绑定方式和调用规则与Oracle实现不同,需对应调整(例如Saxon使用
xmlns:java="http://saxon.sf.net/java-type"进行绑定)。
内容的提问来源于stack exchange,提问作者sunil

