移除 xml 的命名空间

Posted

技术标签:

【中文标题】移除 xml 的命名空间【英文标题】:namespace removal of xml 【发布时间】:2019-02-09 11:51:49 【问题描述】:

我的源代码低于 XML,必须通过添加段进行转换。但也必须删除根节点中添加的命名空间。但无法移除命名空间。

有人可以告诉我在哪里添加到 XSLT。

源 XML:

 <?xml version="1.0" encoding="UTF-8"?>
                    <Header 
                      xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
                        <Main>
                            <Parent2>
                                <status>12</status>
                                <statusmsg>Helo</statusmsg>
                            </Parent2>
                            <Parent3>
                                <Child1>112</Child1>
                                <Child2>Hai</Child2>
                            </Parent3>
                            <Parent4>
                                <Child3>Valley</Child3>
                                <Parent5>
                                    <Child7>Kind</Child7>
                                    <Child8>Pls</Child8>
                                </Parent5>
                            </Parent4>
                        </Main>
                    </Header>

目标 XML:

 <Header>
                        <Main Mainattribute="1">
                            <Parent2 childattribute="1">
                                <status>12</status>
                                <statusmsg>Helo</statusmsg>
                            </Parent2>
                            <Parent3 childattribute="1">
                                <Child1>112</Child1>
                                <Child2>Hai</Child2>
                            </Parent3>
                            <Parent4 childattribute="1">
                                <Child3>Valley</Child3>
                                <Parent5>
                                    <Child7>Kind</Child7>
                                    <Child8>Pls</Child8>
                                </Parent5>
                            </Parent4>
                        </Main>
                    </Header>

XSLT 从以下链接尝试: Populate Attribute and values to all parent nodes of the XML file from 4th parent node

        <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
            <xsl:output method="xml" indent="yes"/>
            <xsl:template match="Main">
                <xsl:copy>
                    <xsl:copy-of select="@*"/>
                    <xsl:attribute name="Mainattribute"><xsl:value-of select="1"/></xsl:attribute>
                    <xsl:apply-templates mode="parent_mode"/>
                </xsl:copy>
            </xsl:template>
            <xsl:template match="*" mode="parent_mode">
                <xsl:copy>
                    <xsl:copy-of select="@*"/>
                    <xsl:attribute name="childattribute"><xsl:value-of select="1"/></xsl:attribute>
                    <xsl:apply-templates/>
                </xsl:copy>
            </xsl:template>
            <xsl:template match="*">
                <xsl:copy>
                    <xsl:copy-of select="@*"/>
                    <xsl:apply-templates/>
                </xsl:copy>
            </xsl:template>
        </xsl:stylesheet>

【问题讨论】:

Remove xmlns from XML using XSLT的可能重复 【参考方案1】:

未使用的命名空间声明不应真正引起任何问题。但如果您确实想摆脱它,在 XSLT 1.0 中,您将不得不创建一个新元素,使用 xsl:element 而不是使用 xsl:copy,因为后者会将命名空间声明复制到。

试试这个 XSLT

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

    <xsl:template match="Main">
        <Main>
            <xsl:copy-of select="@*"/>
            <xsl:attribute name="Mainattribute"><xsl:value-of select="1"/></xsl:attribute>
            <xsl:apply-templates mode="parent_mode"/>
        </Main>
    </xsl:template>

    <xsl:template match="*" mode="parent_mode">
        <xsl:element name="local-name()">
            <xsl:copy-of select="@*"/>
            <xsl:attribute name="childattribute"><xsl:value-of select="1"/></xsl:attribute>
            <xsl:apply-templates/>
        </xsl:element>
    </xsl:template>

    <xsl:template match="*">
        <xsl:element name="local-name()">
            <xsl:copy-of select="@*"/>
            <xsl:apply-templates/>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

如果您可以使用 XSLT 2.0,则可以将 copy-namespaces 添加到 xsl:copy

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

    <xsl:template match="Main">
        <xsl:copy copy-namespaces="no">
            <xsl:copy-of select="@*"/>
            <xsl:attribute name="Mainattribute"><xsl:value-of select="1"/></xsl:attribute>
            <xsl:apply-templates mode="parent_mode"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="*" mode="parent_mode">
        <xsl:copy copy-namespaces="no">
            <xsl:copy-of select="@*"/>
            <xsl:attribute name="childattribute"><xsl:value-of select="1"/></xsl:attribute>
            <xsl:apply-templates/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="*">
        <xsl:copy copy-namespaces="no">
            <xsl:copy-of select="@*"/>
            <xsl:apply-templates/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

【讨论】:

不,不工作。我已经试过了。命名空间已从 Header 节点转移到 Main 节点。有没有办法可以硬删除命名空间。 我在xsltfiddle.liberty-development.net/3NzcBtz 对其进行了测试,它给出了预期的结果。您是否确保&lt;xsl:copy&gt; 的所有实例都替换为&lt;xsl:element&gt;?另外,您使用的是什么 XSLT 处理器? 我正在尝试在freeformatter.com/xsl-transformer.html#ad-output 中进行转换,而且我们的系统也与 1.0 和 2.0 兼容。但不删除命名空间。所以我们不能这样硬删除。谢谢 对不起,它是 XSLT1.0 但是当我将代码更改为元素时,它会成功,但不会为 parent_mode 创建属性。 它没有创建哪些属性?【参考方案2】:

对于 XSLT 2.0 有一个更简单的方法是使用

<xsl:copy-of select="/" copy-namespaces="no"/>

执行深层复制删除所有未使用的命名空间。

【讨论】:

以上是关于移除 xml 的命名空间的主要内容,如果未能解决你的问题,请参考以下文章

PHP 命名空间移除/映射和重写标识符

wix heat 使用 xsl 文件移除命名空间

『XML』XML/XSD命名空间解析

如果命名空间声明在 SOAP 信封上,如何使用 JAXB 解组 SOAP 响应?

VS2015-项目默认的XML命名空间必须是MSBuild XML命名空间

移除指定 global using 命名空间