使用XSLT完全创建新XML并不保留输出XML

时间:2017-10-22 19:29:11

标签: xslt xml-namespaces

我正在尝试将输入XML完全转换为新的XML格式。它不会在输出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中的根标记和其他标记是动态的。转换背后的主要目标是根据字典xml中的值将传入的XML元素和属性转换为另一种语言[如:Spanish]。与post

类似

2 个答案:

答案 0 :(得分:1)

首先,就问题提问。

您的输入有一个文本节点读取

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/>

输出就像你展示的那样。

其次,关于这个问题,你可能已经想过了。

如果我们假设&gt;在示例输入和输出的第一行的末尾是一个错误,因此输入和输出文档应该具有绑定前缀xsdxsi的命名空间声明和默认命名空间,然后您获得的输出没有命名空间声明,因为您指定输出包含$root给出的QName元素,在这种情况下具有值Container

如果您希望输出元素具有相同的扩展名,请替换

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

<xsl:copy>
  ...
</

答案 1 :(得分:0)

如果输入XML具有默认命名空间,则只要使用XSLT 1.0,相关的XSL样式表必须定义namespace-prefix并使用xsl:template的@match属性。因此,以下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>