完全使用 XSLT 创建一个新的 XML 并没有保留输出 XML 上的命名空间

Creating a new XML altogether using XSLT isn't preserving the namespaces on the Output XML

我正在尝试将输入 XML 转换为新的 XML 格式 altogether.It 未保留输出 XML 上的命名空间。我已经尝试了一些来自 SO 的建议,但是由于我正在创建新的根元素,所以它没有保留命名空间。任何帮助深表感谢!提前致谢!

输入XML是:

<Container
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://hgkl.kj.com">
 <Request>
  <Id>Guid</Id>
  <Name>ABC</Name>
 </Request>
</Container>

XSLT:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output  indent="yes"/>


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

 <xsl:template match="/*"> 
   <xsl:variable name="root" select="name()" />
   <xsl:element name="{$root}">
      <xsl:apply-templates select="child::*"/>
   </xsl:element>
 </xsl:template>

<xsl:template match="child::*"> 
  <xsl:element name="Input">
    // rest of the logic
  </xsl:element>
</xsl:template>

</xsl:stylesheet>

预期输出:

<?xml version="1.0" encoding="UTF-8"?>
<Container>
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://hgkl.kj.com">
 <Input>
    // rest of the logic for forming the element
  </Input>
</Container>

XML 中的根标签和其他标签是动态的。转换背后的主要 objective 是根据字典 xml 中的值将传入的 XML 元素和属性转换为另一种语言 [如:西班牙语]。类似于 post

如果您的输入 XML 具有默认名称空间,则只要您使用 XSLT 1.0,相关的 XSL 样式表就必须定义名称空间前缀并使用它的 @match xsl:template 属性。因此,以下 XSLT 样式表将满足您的要求:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:ins="http://hgkl.kj.com"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    >

    <xsl:output  indent="yes"/>

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

    <xsl:template match="/ins:*"> 
        <xsl:variable name="root" select="local-name()"/>
        <xsl:element name="{$root}" namespace="http://hgkl.kj.com">
            <xsl:for-each select="namespace::node()">
                <xsl:copy/>
            </xsl:for-each>
            <xsl:apply-templates select="child::*"/>
        </xsl:element>
    </xsl:template>

    <xsl:template match="ins:*"> 
        <xsl:element name="Input" namespace="http://hgkl.kj.com">
            // rest of the logic
        </xsl:element>
    </xsl:template>

</xsl:stylesheet>

[结果]

<?xml version="1.0" encoding="utf-8"?>
<Container xmlns="http://hgkl.kj.com" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   <Input>
    // rest of the logic
   </Input>
</Container>

首先,关于提问的问题。

您输入的文本节点显示为

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://hgkl.kj.com">

作为输入的子项。它不会传播到输出,因为最外层元素的模板(使用 match="/*")仅将模板应用于子元素。如果你改变

  <xsl:apply-templates select="child::*"/> 

在该模板中

  <xsl:apply-templates/>

输出如您所见。

其次,关于你可能有意提出的问题。

如果我们假设示例输入和输出中第一行末尾的 > 是错误的,那么输入和输出文档应该具有命名空间声明绑定前缀 xsdxsi 和默认命名空间,那么您得到的输出没有命名空间声明,因为您指定输出包含一个元素,其 QName 由 $root 给出,在本例中其值为 Container.

如果您想要一个具有相同扩展名称的输出元素,请替换

<xsl:element name="{$root}">
  ...
</

<xsl:copy>
  ...
</