2011-06-06 68 views
4

我有一个如下所示的xml。如何在xsl翻译时忽略命名空间

<?xml version="1.0" encoding="UTF-8"?> 
<books xmlns="http://www.books.com/SRK"> 
    <name>English</name> 
</books 

我需要使用xsl进行翻译后的以下输出。

<?xml version="1.0" encoding="UTF-8"?> 
<books> 
    <name>English</name> 
</books> 

我需要一个xsl来忽略命名空间。我尝试了一些东西,但它没有与命名空间一起工作。

我需要你的帮助。你的帮助将不胜感激。

+3

欢迎SO。发布代码时,请缩进4个空格或在编辑器中使用“{}”按钮,以便正确显示。我为你修好了。 – 2011-06-06 14:42:11

+0

您可以发布更复杂的输入样本吗? – 2011-06-11 05:26:28

回答

5

这种转变

<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()[not(self::*)]"> 
    <xsl:copy/> 
</xsl:template> 

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

当应用于提供的XML文档

<books xmlns="http://www.books.com/SRK"> 
    <name>English</name> 
</books> 

产生想要的,正确的结果

<books> 
    <name>English</name> 
</books> 
+0

你能解释一下'[not(self :: *)]'的需要吗?我已经测试没有它,它也适用。 (+1) – 2011-06-06 14:43:38

+0

似乎也只有第二个模板是必要的。我对吗? – 2011-06-06 14:47:48

+0

@empo:对于这个特定的XML文档,只需要第二个模板就会生成想要的结果。但是,XML文档通常具有:属性,注释节点,PI节点。我的解决方案适用于任何具有这些类型节点混合的XML文档。 – 2011-06-06 15:59:19

2

其工作只有当我包括上述模板,如果我添加一些其他模板比以上一个,那么翻译是不是工作。没有模板得到执行。

可能您错过了book元素的名称空间声明。例如:

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:b="http://www.books.com/SRK" 
    exclude-result-prefixes="b"> 

    <xsl:output omit-xml-declaration="yes" indent="yes"/> 
    <xsl:strip-space elements="*"/> 

     <!-- @dimitre's answer templates --> 

    <xsl:template match="b:name"> 
      <!-- your template for name --> 
    </xsl:template> 

</xsl:stylesheet> 

此外,请务必使用local-name()函数来获取元素的名称,没有相关的命名空间。


<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:b="http://www.books.com/SRK" 
    exclude-result-prefixes="b"> 
    <xsl:output method="xml" encoding="UTF-8" indent="yes"/> 


    <xsl:template match="b:input"> 
     <xsl:element name="{local-name(.)}"> 
       <xsl:apply-templates select="b:name"/> 
     </xsl:element> 
    </xsl:template> 

    <xsl:template match="b:name"> 
     <xsl:element name="{local-name()}"> 
      <xsl:value-of select="."/> 
     </xsl:element> 
      <lhs> 
       <xsl:apply-templates select="following-sibling::b:lhs/b:evaluate"/> 
      </lhs> 
    </xsl:template> 

    <xsl:template match="b:evaluate"> 
     Something to evaluate...  
    </xsl:template> 

</xsl:stylesheet> 

得到:

<?xml version="1.0" encoding="UTF-8"?> 
<input> 
<name>English</name> 
<lhs> 
     Something to evaluate...  
    </lhs> 
</input> 

第二示例

您可以创建一个名为local @ identity.xsl的单独转换,其中包含@Dimitre解决方案。然后你可以在你的转换中导入它。因为你有一个命名空间,搭配元素,你必须改变所有您的XPath,包括您将在变换声明前缀,如下面的例子:

<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:brl="http://www.xyz.com/BRL" 
    exclude-result-prefixes="brl" 
    version="1.0"> 

    <xsl:import href="local-identity.xsl"/> 

    <xsl:output method="xml" indent="yes"/> 
    <xsl:strip-space elements="*"/> 


    <xsl:template match="/brl:rule"> 
    <!-- do your staff, select using brl prefix --> 
    <xsl:apply-templates/> 
    </xsl:template> 

</xsl:stylesheet> 
+1

使用exclude-result-prefixes =“b”的想法帮助我解决了一个相关的问题。谢谢! – louisgab 2016-11-28 14:06:13