XSLT删除根命名空间并将命名空间添加到另一个元素

时间:2016-07-05 23:22:44

标签: xml xslt namespaces

我有一个输入xml -

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Root xmlns="http://www.somenamespace">
    <Child1>
        <A>a</A>
        <B>b</B>
    </Child1>
    <Child2>
        <C>c</C>
        <D>d</D>
    </Child2>
</Root>

我希望转换后的输出xml从root中删除命名空间并将其添加到Element Child1,而不是像这样 -

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<NewRoot>
    <NewChild1 xmlns="http://www.somenamespace">
        <A>a</A>
        <B>b</B>
    </NewChild1>
    <NewChild2>
        <C>c</C>
        <D>d</D>
    </NewChild2>
</NewRoot>

我的xslt看起来像 -

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
            xmlns="http://www.somenamespace"
            xmlns:test="http://www.somenamespace"
            exclude-result-prefixes="test">
    <xsl:output method="xml" indent="yes" version="1.0" encoding="UTF-8" standalone="yes"/>
    <xsl:template match="/">
    <NewRoot>
        <xsl:apply-templates select="test:Root/test:Child1"/>
        <xsl:apply-templates select="test:Root/test:Child2"/>
    </NewRoot>
    </xsl:template>
    <xsl:template match="test:Root/test:Child1">
         <NewChild1> <xsl:value-of select="current()"/> </NewChild1>
    </xsl:template>
    <xsl:template match="test:Root/test:Child2">
         <NewChild2> <xsl:value-of select="current()"/> </NewChild2>
    </xsl:template>
</xsl:stylesheet>

目前,这会将命名空间添加到NewRoot元素。

2 个答案:

答案 0 :(得分:1)

您可以按如下方式进行更改:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
            xmlns:test="http://www.somenamespace"
            exclude-result-prefixes="test">
    <xsl:output method="xml" indent="yes" version="1.0" encoding="UTF-8" standalone="yes"/>
    <xsl:template match="/">
    <NewRoot>
        <xsl:apply-templates select="test:Root/test:Child1"/>
        <xsl:apply-templates select="test:Root/test:Child2"/>
    </NewRoot>
    </xsl:template>
    <xsl:template match="test:Root/test:Child1">
         <test:NewChild1> <xsl:value-of select="current()"/> </test:NewChild1>
    </xsl:template>
    <xsl:template match="test:Root/test:Child2">
         <NewChild2> <xsl:value-of select="current()"/> </NewChild2>
    </xsl:template>
</xsl:stylesheet>

即。不要声明默认命名空间(xmlns="..."),而是将NewChild1显式放在http://www.somenamespace命名空间中。

这就是你提出的问题,即修改样式表到&#34;从root中删除命名空间并将其添加到Element Child1&#34 ;;但它不会在所有细节中生成您的示例输出(例如,<A><B>元素仍未保留,因为您没有请求帮助。我不会完全重写您的样式表以重现可能不是您想要关注的示例输出的各个方面,而是将其留在那里,让您提供有关您特别需要帮助的其他内容的反馈。

在所有这些中,如果您确保了解命名空间声明,命名空间前缀命名空间之间的区别,它将节省时间并使通信更容易元素在。

答案 1 :(得分:0)

我建议你这样做:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns="http://www.somenamespace"
exclude-result-prefixes="ns">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="/">
    <NewRoot>
        <xsl:apply-templates/>
    </NewRoot>
</xsl:template>

<xsl:template match="ns:Child1">
    <NewChild1 xmlns="http://www.somenamespace">
        <xsl:copy-of select="*"/>
    </NewChild1>
</xsl:template>

<xsl:template match="ns:Child2">
    <NewChild2>
        <xsl:apply-templates mode="no-namespace"/>
    </NewChild2>
</xsl:template>

<xsl:template match="*" mode="no-namespace">
    <xsl:element name="{local-name()}">
        <xsl:apply-templates/>
    </xsl:element>
</xsl:template>

</xsl:stylesheet>