You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 14:04:51