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

Eclipse中XSLT输出多余msxsl命名空间问题求助

解决XSLT转换在Eclipse中输出带多余命名空间前缀的问题

我之前从Visual Studio的MSXML处理器切换到Eclipse的Xalan/Saxon处理器时,也碰到过一模一样的命名空间处理差异问题。核心原因是不同XSLT处理器对命名空间继承和前缀输出的逻辑不一样:VS的MSXML会自动复用父节点的命名空间声明,而Eclipse里的处理器会严格按照你XSLT中的命名空间绑定来输出前缀,哪怕完全没必要。

针对你的情况,有几个简单的修复方案:

方案1:让MessageType继承父节点的命名空间

原XSLT中你用xsl:element显式指定了命名空间,但父节点CustInvoiceJour已经处于http://schemas.microsoft.com/dynamics/2008/01/documents/SalesInvoice命名空间下,完全可以去掉namespace属性,让元素自动继承上下文的命名空间:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="http://schemas.microsoft.com/dynamics/2008/01/documents/SalesInvoice">
  <xsl:output method="xml" indent="yes" />
  <xsl:strip-space elements="*" />

  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()" />
    </xsl:copy>
  </xsl:template>

  <xsl:template match="msxsl:SalesType">
    <xsl:choose>
      <xsl:when test="(../msxsl:SalesType) = 'ReturnItem'">
        <xsl:element name="MessageType">384</xsl:element>
      </xsl:when>
      <xsl:otherwise>
        <xsl:element name="MessageType">380</xsl:element>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
</xsl:stylesheet>

这样修改后,Eclipse的处理器会自动让MessageType继承父节点的命名空间,不会额外添加msxsl前缀和声明。

方案2:设置默认命名空间并排除多余前缀

如果你希望更明确地控制命名空间,可以把目标命名空间设为XSLT的默认命名空间,同时用exclude-result-prefixes告诉处理器不要输出msxsl前缀:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" 
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
                xmlns:msxsl="http://schemas.microsoft.com/dynamics/2008/01/documents/SalesInvoice"
                xmlns="http://schemas.microsoft.com/dynamics/2008/01/documents/SalesInvoice"
                exclude-result-prefixes="msxsl">
  <xsl:output method="xml" indent="yes" />
  <xsl:strip-space elements="*" />

  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()" />
    </xsl:copy>
  </xsl:template>

  <xsl:template match="msxsl:SalesType">
    <xsl:choose>
      <xsl:when test="(../msxsl:SalesType) = 'ReturnItem'">
        <MessageType>384</MessageType>
      </xsl:when>
      <xsl:otherwise>
        <MessageType>380</MessageType>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
</xsl:stylesheet>

这里直接输出<MessageType>即可,因为默认命名空间已经和目标命名空间一致,exclude-result-prefixes="msxsl"会阻止处理器在输出中添加msxsl的命名空间声明。

为什么VS里没问题?

Visual Studio使用的MSXML处理器在命名空间处理上更灵活,当它检测到子节点的命名空间和父节点完全一致时,会自动省略前缀和重复的命名空间声明,而Eclipse常用的Xalan或Saxon处理器则会严格遵循XSLT中的命名空间绑定规则,所以才会出现这种差异。

内容的提问来源于stack exchange,提问作者Mike Dole

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:00:23