XSL repeat/keep 每个节点中的命名空间声明

XSL repeat/keep the namespace declaration in every node

我必须做一个 XSL 应该:

输入:

      <oldRoot xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="old:namspace">
<Lists xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="old:namspace">
  <header xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="old:namspace">
    <createDate>2016-04-20</createDate>
  </header>
  <ListCode>1</ListCode>
    <ListLocalFlag xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="old:namspace" i:nil="true"/>
    <ListStatus>1</ListStatus>
    <addValueHere xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="old:namspace" i:nil="true"/> 
<dontTouchMe/>
</Lists>

期望的输出:

      <newRoot xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://new.namspace" processid="1">
<Lists xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://new.namspace">
  <header xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://new.namspace">
    <createDate>2016-04-20</createDate>
  </header>
  <ListCode>1</ListCode>
    <ListLocalFlag xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://new.namspace" i:nil="true"/>
    <ListStatus>1</ListStatus>
    <addValueHere xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://new.namspace">27</addValueHere>
<dontTouchMe/>
</Lists>

目前我试过的(没用,我试了很多废话):

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
            xmlns="http://new.namspace"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            xmlns:i="DeleteMeLikeThisOrNeedCorrectURI?"
            xmlns:msxsl="urn:schemas-microsoft-com:xslt"
            xmlns:old="old:namspace"
            exclude-result-prefixes="i old msxsl">
<xsl:output omit-xml-declaration="no" indent="yes" method="xml"/>

<xsl:namespace-alias stylesheet-prefix="i" result-prefix="xsi"/>

<xsl:variable name="processid" select="1"/>
<xsl:variable name="nsmapdocString">
<root xml:space="preserve" xmlns="" >
  <namespace source="old:namspace" target="http://new.namspace"/>
</root>
</xsl:variable>
<xsl:param name="nsmapdoc" select="msxsl:node-set($nsmapdocString)" />

<xsl:template match="/" name="root">
<newRoot processid="{$processid}" xmlns:xsi="http://www.w3.or//2001/XMLSchema-instance" xmlns="http://new.namspace">
  <xsl:for-each select="node()|@*">
    <xsl:apply-templates/>
  </xsl:for-each>
</newRoot>
</xsl:template>

<xsl:template match="*[(local-name()='addValueHere' or local-name()='addSameValueHere2') and not(node())]" name="setValue">
<xsl:variable name="old-ns" select="namespace-uri()"/>
<xsl:variable name="map-entry" select="$nsmapdoc/root/namespace[@source=$old-ns]"/>
<xsl:variable name="new-ns">
  <xsl:choose>
    <xsl:when test="$map-entry">
      <xsl:value-of select="$map-entry/@target"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="$old-ns"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:variable>
<xsl:element name="{local-name()}" namespace="{$new-ns}">
    <xsl:copy-of select="27" />      
  <!--<xsl:apply-templates/>-->
</xsl:element>
</xsl:template>

<xsl:template match="*[not((local-name()='addValueHere') and not(local-name()='addSameValueHere2')) and not(node())]" name="setRestNil">
<xsl:variable name="old-ns" select="namespace-uri()"/>
<xsl:variable name="map-entry" select="$nsmapdoc/root/namespace[@source=$old-ns]"/>
<xsl:variable name="new-ns">
  <xsl:choose>
    <xsl:when test="$map-entry">
      <xsl:value-of select="$map-entry/@target"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="$old-ns"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:variable>
<xsl:element name="{local-name()}" namespace="{$new-ns}">     
  <xsl:attribute name="xsi:nil" namespace="http://www.w3.org/2001/XMLSchema-instance">
    <xsl:value-of select="true()"/>
  </xsl:attribute>
</xsl:element>
</xsl:template>
</xsl:stylesheet>

XSLT 执行从一棵树到另一棵树的转换,然后序列化程序开始生成结果树的词法表示 XML。标准序列化程序总是会从树中删除多余的命名空间,您无法在 XSLT 代码中做任何事情来阻止这种情况;实现它的唯一方法是编写自己的序列化程序。

很难满足这个要求的原因是它是一个不好的要求。 XML 的明智消费者不应该要求它包含冗余命名空间,因此永远不应该要求生成它们。