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



我写了"排除结果前缀",即便如此,我也在输出中看到名称空间出现。

<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 中的所有命名空间出现?

xsl:stylesheetexclude-result-prefixes 属性,当指定为 "yes" 时,要求删除 litreral result 元素的任何命名空间节点(仅),这些节点是继承的,并且不定义文本结果元素的命名空间 uri 和前缀。

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

"exclude-result-prefixes 只是删除 xmlns:foo=" 属性 结果的根标记。

这是一个反例

<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>

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

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

我们看到:

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

  2. 前缀为 "z" 的命名空间根本不会从任何文本元素中删除。

这显示了一个简单的事实,即如果命名空间不在 LRE(文本结果元素)上,即使命名空间节点位于 LRE 上但正在定义元素所属的命名空间,指定 exclude-result-prefixes="yes" 也无法删除命名空间

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

例如,将传统标识规则替换为以下内容:

<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>

上述转换将任何元素或属性替换为属于"no 命名空间"的相应元素或属性。它的一个潜在用途是将具有默认命名空间的文档转换为没有此类命名空间的文档。

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

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

转换的结果是

<x>
   <y attr="someValue"/>
</x>

最后警告:

如果应用于包含两个元素(或两个属性

)的文档,这些元素(或两个属性)具有相同的本地名称但属于两个不同的命名空间,则此转换可能会有害 - 转换将这些元素(或属性)替换为都属于同一命名空间(无命名空间)的元素(或属性)。

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维基)

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

尝试在样式表中使用它:

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

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

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

最新更新