如何通过在XSLT中编写单个语句来避免输出中的所有命名空间

时间:2012-06-25 11:22:14

标签: xslt

我写了“exclude-result-prefixes”,然后我在输出中看到了名称空间出现的外观。

<xsl:stylesheet
    version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt"
    xmlns:simple="Simple name space"
    xmlns:xlink="http://www.w3.org/1999/xlink"
    xmlns:tcm="http://www.tridion.com/ContentManager/5.0"
    xmlns:xh="http://www.w3.org/1999/xhtml"
    xmlns:i="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:transform-ext="urn:tridion:transform-ext"
    xmlns="http://www.w3.org/1999/xhtml"
    exclude-result-prefixes="#default simple xh">

实际输出

<strong xmlns="Simple name space">abcd
    <link xmlns="http://www.w3.org/1999/xhtml">
        <text>Header</text>
    </link>
</strong>

是否有任何方法可以通过编写单个语句来排除所有命名空间。

这里我明确提到了

exclude-result-prefixes="#default simple xh"

如何避免xslt中的所有命名空间外观?

4 个答案:

答案 0 :(得分:8)

exclude-result-prefixes的{​​{1}}属性,当指定为xsl:stylesheet时,要求删除继承的 litreral结果元素(仅)的任何命名空间节点并且不要定义文字结果元素的namespace-uri和prefix。

Markus Jarderot在答案中的以下陈述是错误的

  

“exclude-result-prefixes只删除xmlns:foo =”“属性   结果的根标签。“

以下是反例

"yes"

当此转换应用于任何XML文档(未使用)时,结果为:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:z="z:z" exclude-result-prefixes="z">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="/">
  <z:x xmlns:z="z:z">
   <z:y/>
  </z:x>
 </xsl:template>
</xsl:stylesheet>

我们看到了

  1. 具有值(namespace-uri)“z:z”的命名空间的命名空间节点(和定义)不会从顶部元素中删除(Markus Jarderot称之为“根标记”)。

  2. 根本不会从任何文字元素中删除前缀为<z:x xmlns:z="z:z"> <z:y/> </z:x> 的命名空间。

  3. 这显示了一个简单的事实,即如果命名空间不在LRE(文字结果元素)上,并且即使命名空间节点在LRE上但是正在定义命名空间,则指定"z"也不能删除命名空间元素所属的

    为了从它所属的命名空间中删除一个元素,或者从非LRE元素中删除命名空间,我们需要指定一些额外的处理。

    一个例子是用以下内容替换传统的身份规则:

    exclude-result-prefixes="yes"

    上述转换用任何属于“no namespace”的元素或属性替换任何元素或属性。它的一个潜在用途是将具有默认命名空间的文档转换为没有这样的文档。

    例如,应用于以下源XML文档

    <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:apply-templates/>
         </xsl:copy>
     </xsl:template>
    
     <xsl:template match="*">
      <xsl:element name="{local-name()}">
       <xsl:apply-templates select="node()|@*"/>
      </xsl:element>
     </xsl:template>
    
     <xsl:template match="@*">
      <xsl:attribute name="{local-name()}">
       <xsl:value-of select="."/>
      </xsl:attribute>
     </xsl:template>
    </xsl:stylesheet>
    

    转化的结果是

    <z:x xmlns:z="z:z">
        <z:y z:attr="someValue"/>
    </z:x>
    

    最后发出警告

    如果应用于包含两个具有相同本地名称但属于两个不同命名空间的元素(或两个属性)的文档,则此转换可能有害 - 转换将这些转换为属于两个属性的元素(或属性)。相同的命名空间(没有命名空间)。

答案 1 :(得分:3)

exclude-result-prefixes只删除结果根标记上的xmlns:foo=""属性。标签仍然绑定到同一名称空间。由于标签没有任何匹配的前缀,因此使用默认命名空间。

如果您希望完全删除命名空间,可以使用以下样式表:

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

    <xsl:template match="/|comment()|processing-instruction()">
        <xsl:copy>
            <xsl:apply-templates/>
        </xsl:copy>
    </xsl:template>

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

    <xsl:template match="@*">
        <xsl:attribute name="{local-name()}">
            <xsl:value-of select="."/>
        </xsl:attribute>
    </xsl:template>
</xsl:stylesheet>

(来源:TEI wiki

答案 2 :(得分:2)

exclude-result-prefixes属性(在某些情况下)将从输出中删除未使用的命名空间声明。它永远不会删除实际上用于结果中的元素和属性的名称空间:也就是说,它永远不会更改元素和属性的名称以将它们放在不同的名称空间(或没有名称空间)中。如果您希望元素不在命名空间中,则必须避免在生成它们时将它们放在命名空间中,无论是使用文字结果元素,xsl:element还是xsl:copy。

答案 3 :(得分:0)

尝试在样式表中使用它:

<stylesheet
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:xhtml="http://www.w3.org/1999/xhtml"   ...etc >

我在一些标签中有这个:xmlns="http://www.w3.org/1999/xhtml,所以我添加了这两行,现在就可以了。

这个来源帮助了我:http://xmlplease.com/xhtmlxhtml