Oxygen调试器运行XSLT报错,正常执行无问题求助
问题
使用Oxygen 24搭配Saxon-EE 9.9.1.7时,XSLT在调试器中运行失败,但直接执行能生成预期输出。
源XML文档
<MSG02> <IDOC BEGIN="1"> <E1EDK01 SEGMENT="1"> <BELNR>1</BELNR> </E1EDK01> <E1EDK03 SEGMENT="1"> <IDDAT>001</IDDAT> <DATUM>20240430</DATUM> </E1EDK03> <E1EDKT1 SEGMENT="1"> <TDID>Z001</TDID> <TSSPRAS>D</TSSPRAS> <TSSPRAS_ISO>DE</TSSPRAS_ISO> <E1EDKT2 SEGMENT="1"> <TDLINE>POconfType:accept;</TDLINE> <TDFORMAT>=</TDFORMAT> </E1EDKT2> </E1EDKT1> <E1EDKT1 SEGMENT="1"> <TDID>Z001</TDID> <TSSPRAS>E</TSSPRAS> <TSSPRAS_ISO>EN</TSSPRAS_ISO> <E1EDKT2 SEGMENT="1"> <TDLINE>POconfType:accept;</TDLINE> <TDFORMAT>=</TDFORMAT> </E1EDKT2> </E1EDKT1> </IDOC> </MSG02>
使用的XSLT代码
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:saxon="http://saxon.sf.net/" exclude-result-prefixes="#all"> <xsl:param name="xquery-param1" as="xs:string" expand-text="no"><![CDATA[ element E1EDKT1 {attribute SEGMENT {"1"}, element TDID { "ZG04" }, if (exists(/*/IDOC/E1EDKT1[TDID="ZG04"]/E1EDKT2/TDLINE)) then (element TSSPRAS {"E"}, element TSSPRAS_ISO {"EN"}, for $kt in (/*/IDOC/E1EDKT1[TDID="ZG04"][1]/E1EDKT2/TDLINE) return element E1EDKT2 {attribute SEGMENT {"1"}, $kt } ) else(), if (exists(/*/IDOC/E1EDK01/BELNR)) then ( element E1EDKT2 {attribute SEGMENT {"1"}, element TDLINE { concat("DateOfSupply:",/*/IDOC/E1EDK03[IDDAT="001"]/DATUM/concat(substring(.,1,4),"-",substring(.,5,2),"-",substring(.,7,2))) } } ) else() } ]]></xsl:param> <xsl:output indent="yes"/> <xsl:variable name="xquery1" select="saxon:compile-query($xquery-param1)"/> <xsl:template match="/" name="xsl:initial-template"> <xsl:apply-templates select="*"/> </xsl:template> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="E1EDKT1[1]"> <xsl:copy-of select="saxon:query($xquery1)"/> </xsl:template> </xsl:stylesheet>
调试前警告
- For parameter 'xquery-param1, the variable/parameter $kt should be placed in a 'Text Value Template'
调试时错误
- W Evaluation will always throw a dynamic error: Namespace prefix {myfunc} has not been declared
- E Internal error evaluating template rule at line 29 in module file:/C:/...
解决方案
1. 修复XQuery中的变量引用语法
调试器的静态语法检查比直接执行更严格,XQuery元素构造中引用变量必须使用文本值模板(大括号包裹),否则会被识别为普通文本。修改XQuery片段里的$kt部分:
element E1EDKT2 {attribute SEGMENT {"1"}, {$kt} }
2. 解决myfunc命名空间未声明错误
这个错误属于调试环境的异常问题,按以下步骤排查:
- 清理Oxygen缓存:依次点击
Tools > Preferences > Global > Clear Cache,重启Oxygen后重试调试。 - 检查调试配置:确认调试时指定的Saxon版本为Saxon-EE 9.9.1.7,避免版本不兼容。
- 排查关联文件:确认所有打开的XML/XSLT文件中没有未声明的
myfunc前缀,防止调试器误关联旧文件。
3. 替代动态XQuery逻辑(可选)
动态编译XQuery容易触发调试器的语法分析告警,可将XQuery逻辑直接转为XSLT模板实现,替换saxon:compile-query和saxon:query调用,示例如下:
<xsl:template match="E1EDKT1[1]"> <E1EDKT1 SEGMENT="1"> <TDID>ZG04</TDID> <xsl:if test="exists(/MSG02/IDOC/E1EDKT1[TDID='ZG04']/E1EDKT2/TDLINE)"> <TSSPRAS>E</TSSPRAS> <TSSPRAS_ISO>EN</TSSPRAS_ISO> <xsl:for-each select="/MSG02/IDOC/E1EDKT1[TDID='ZG04'][1]/E1EDKT2/TDLINE"> <E1EDKT2 SEGMENT="1"> <xsl:copy-of select="."/> </E1EDKT2> </xsl:for-each> </xsl:if> <xsl:if test="exists(/MSG02/IDOC/E1EDK01/BELNR)"> <E1EDKT2 SEGMENT="1"> <TDLINE> <xsl:value-of select="concat('DateOfSupply:',format-date(xs:date(concat(substring(/MSG02/IDOC/E1EDK03[IDDAT='001']/DATUM,1,4),'-',substring(.,5,2),'-',substring(.,7,2))), '[Y0001]-[M01]-[D01]'))"/> </TDLINE> </E1EDKT2> </xsl:if> </E1EDKT1> </xsl:template>
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

