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

XSLT复制节点丢失祖先已定义的xmlns属性,如何保留冗余属性?

问题:保留XSLT转换中后代节点的冗余xmlns属性

使用XSLT复制节点和属性时,当xmlns属性已由祖先节点定义,复制后代节点时这些属性会丢失。从功能上看,后代节点的这类属性定义属于冗余(若理解有误请指正),推测这是属性未被写入输出的原因,但没找到相关依据。请问有没有办法保留后代节点上这些重复/冗余的xmlns属性?


操作环境

  • openjdk 11.0.19 2023-04-18
  • Ubuntu 22.04
  • Saxon HE 11.5

使用的XSLT(标识转换)

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

示例输入XML

祖先节点<OAI-PMH>与后代节点<oai_qdc:qualifieddc>存在4个重复的xmlns属性:

<?xml version="1.0" encoding="UTF-8"?>
<OAI-PMH xmlns="http://www.openarchives.org/OAI/2.0/"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns:oai_qdc="http://worldcat.org/xmlschemas/qdc-1.0/"
         xmlns:dcterms="http://purl.org/dc/terms/"
         xmlns:dc="http://purl.org/dc/elements/1.1/"
         xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd">
  <ListRecords>
    <record>
      <header>
        <datestamp>1998-07-05T07:00:00Z</datestamp>
      </header>
      <metadata>
        <oai_qdc:qualifieddc xmlns:oai_qdc="http://worldcat.org/xmlschemas/qdc-1.0/" 
                             xmlns:dcterms="http://purl.org/dc/terms/" 
                             xmlns:dc="http://purl.org/dc/elements/1.1/" 
                             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                             xsi:schemaLocation="http://worldcat.org/xmlschemas/qdc-1.0/ http://worldcat.org/xmlschemas/qdc-1.0/qdc-1.0.xsd">
          <dc:title>Some Title</dc:title>
        </oai_qdc:qualifieddc>
      </metadata>
    </record>
  </ListRecords>
</OAI-PMH>

转换后输出XML(冗余xmlns属性丢失)

<?xml version="1.0" encoding="UTF-8"?>
<OAI-PMH xmlns="http://www.openarchives.org/OAI/2.0/" 
         xmlns:dc="http://purl.org/dc/elements/1.1/"
         xmlns:dcterms="http://purl.org/dc/terms/"
         xmlns:oai_qdc="http://worldcat.org/xmlschemas/qdc-1.0/"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd">
  <ListRecords>
    <record>
      <header>
        <datestamp>1998-07-05T07:00:00Z</datestamp>
      </header>
      <metadata>
        <oai_qdc:qualifieddc xsi:schemaLocation="http://worldcat.org/xmlschemas/qdc-1.0/ http://worldcat.org/xmlschemas/qdc-1.0/qdc-1.0.xsd">
          <dc:title>Some Title</dc:title>
        </oai_qdc:qualifieddc>
      </metadata>
    </record>
  </ListRecords>
</OAI-PMH>

解答

原因说明

你说得没错,后代节点上重复的xmlns属性确实属于冗余——XML的命名空间作用域是从声明节点向下传递的,后代节点继承了祖先的命名空间声明,所以这些重复声明在语义上完全多余。XSLT处理器(比如Saxon)在序列化输出时会自动优化掉这类冗余声明,这是符合XML规范的行为。

解决方案

如果必须保留这些冗余的xmlns属性,可以通过以下两种方式实现:

方法1:使用Saxon扩展序列化参数

Saxon提供了扩展参数saxon:suppress-redundant-namespaces,将其设置为no即可强制保留所有命名空间声明,包括冗余的。修改XSLT如下:

<xsl:stylesheet version="2.0" 
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:saxon="http://saxon.sf.net/">
  <xsl:output method="xml" indent="yes" saxon:suppress-redundant-namespaces="no"/>
  
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

注意需要将XSLT版本指定为2.0+,并声明Saxon的命名空间。

方法2:显式复制命名空间属性

如果需要兼容更多处理器,可以显式匹配命名空间节点,并将其转换为普通的xmlns属性输出。修改模板如下:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="@*|node()">
    <xsl:copy>
      <!-- 显式复制所有命名空间节点为xmlns属性 -->
      <xsl:for-each select="namespace::*">
        <xsl:attribute name="xmlns:{local-name()}" namespace="">
          <xsl:value-of select="."/>
        </xsl:attribute>
      </xsl:for-each>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
  
  <!-- 避免重复处理已转换的命名空间属性 -->
  <xsl:template match="@xmlns:*"/>
</xsl:stylesheet>

这个方法通过遍历节点的命名空间节点,手动创建对应的xmlns属性,同时忽略原本的xmlns属性(避免重复),从而强制保留所有层级的命名空间声明。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 19:54:53