xml - 如何从 XML 元素中删除一个特定的命名空间

标签 xml xslt namespaces

我一直在寻找这个特定的案例,但没有找到。我有这个 XML,除了这三个元素之外还有其他元素,但它们无关紧要。相关元素有两个 namespace 附加到它。我想删除 xmlns:two 所以在输出中只有第一个 xmlns 存在。

<?xml version="1.0" encoding="UTF-8"?>
<Header>
    <one:id xmlns:one="http://x.com/xsd/so" 
        xmlns:two="http://x.com/xsd/woa.xsd">555</one:id>
    <one:protocolVersion xmlns:one="http://x.com/xsd/so" 
        xmlns:two="http://x.com/xsd/woa.xsd">2.0</one:protocolVersion>
    <one:userId xmlns:one="http://x.com/xsd/so" 
        xmlns:two="http://x.com/xsd/woa.xsd">12345</one:userId>
</Header>

现在我想要的是删除 xmlns:two
<?xml version="1.0" encoding="UTF-8"?>
<Header>
    <one:id xmlns:one="http://x.com/xsd/so">555</one:id>
    <one:protocolVersion xmlns:one="http://x.com/xsd/so">2.0</one:protocolVersion>
    <one:userId xmlns:one="http://x.com/xsd/so">12345</one:userId>
</Header>

我试过这样的事情,但它删除了错误的命名空间。它删除了前缀相同的命名空间。
<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:two="http://x.com/xsd/woa.xsd" 
    xmlns:one="http://x.com/xsd/so">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:strip-space elements="*"/>

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

    <xsl:template match="one:id">
        <xsl:element name="{local-name()}">
            <xsl:copy-of select="namespace::*[not(. = namespace-uri(..))]"/>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

最佳答案

有很多事情会阻止它创建您所描述的结果:

在这里,您只复制元素不使用的命名空间,而不是它使用的命名空间:

<xsl:copy-of select="namespace::*[not(. = namespace-uri(..))]"/>

在这里,您将在空命名空间(无命名空间)中创建一个元素:
<xsl:element name="{local-name()}">

您已声明 onetwo XSLT 样式表根元素上的命名空间,这意味着它们将包含在输出文档的根元素中。

为了获得您所描述的结果,您可以使用以下命令:
<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:strip-space elements="*"/>

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

    <xsl:template match="one:*" xmlns:one="http://x.com/xsd/so" >
        <xsl:element name="{name()}" namespace="{namespace-uri()}">
            <xsl:apply-templates select="node()|@*"/>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

或者,您可以使用更通用的、与命名空间无关的方法:
<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:strip-space elements="*"/>

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

    <xsl:template match="*">
        <xsl:element name="{name()}" namespace="{namespace-uri()}">
            <xsl:apply-templates select="node()|@*"/>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

这两者都会产生你所说的你想要的输出。

关于xml - 如何从 XML 元素中删除一个特定的命名空间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50986281/

相关文章:

Android XML FrameLayout 和 BottomNavigationView

html - XSLT - CSS 样式表的所有元素属性的组合

ruby-on-rails - Ruby on Rails 路由 : Namespace with more params

c++ - 将单个类导入命名空间似乎要求命名空间之间不存在函数名称冲突

visual-studio-2010 - Visual Studio 自动调整设计器文件上的命名空间

java - android.view.InflateException : Binary XML file line #17: Error inflating class android. support.design.widget.NavigationView

mysql - 如何将现有数据库从 Domino 服务器迁移到关系数据库 (MySQL)

python - 在 Python 中解析 XML 字符串

xml - XSLT 高效识别给定范围内的重复节点

html - 在两个同样具有特定属性的 <li> 元素之间选择具有特定属性值的 <li> 元素