【问题标题】:XSLT: Add namespace to root elementXSLT:将命名空间添加到根元素
【发布时间】:2011-02-10 19:32:03
【问题描述】:

我需要更改根元素中的命名空间,如下所示:

输入文件:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<foo xsi:schemaLocation="urn:isbn:1-931666-22-9 http://www.loc.gov/ead/ead.xsd"
xmlns:ns2="http://www.w3.org/1999/xlink" xmlns="urn:isbn:1-931666-22-9"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

想要的输出:

<foo audience="external" xsi:schemaLocation="urn:isbn:1-931666-22-9
     http://www.loc.gov/ead/ead.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-
    instance" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="urn:isbn:1-931666-22-9">

我在复制整个文档时尝试这样做,然后再给出任何其他转换说明,但以下方法不起作用:

<xsl:template match="* | processing-instruction() | comment()">
    <xsl:copy copy-namespaces="no">
        <xsl:for-each select=".">
            <xsl:attribute name="audience" select="'external'"/>
            <xsl:namespace name="xlink" select="'http://www.w3.org/1999/xlink'"/>
        </xsl:for-each>
        <xsl:copy-of select="@*"/>
        <xsl:apply-templates/>
    </xsl:copy>
</xsl:template>

感谢您的建议!

【问题讨论】:

  • 好问题 (+1)。有关完整的 XSLT 1.0 和 2.0 解决方案,请参阅我的答案。 :)

标签: xslt namespaces


【解决方案1】:

XSLT 2.0 不是解决此问题所必需的。

这是一个 XSLT 1.0 解决方案,它与 XSLT 2.0 一样好用(只需将 version 属性更改为 2.0):

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

 <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:copy-of select=
        "namespace::*
           [not(name()='ns2')
          and
            not(name()='')
           ]"/>

      <xsl:copy-of select=
       "document('')/*/namespace::*[name()='xlink']"/>

      <xsl:copy-of select="@*"/>

      <xsl:attribute name="audience">external</xsl:attribute>
   </xsl:element>
 </xsl:template>
</xsl:stylesheet>

当上述转换应用于此 XML 文档时

<foo
xsi:schemaLocation="urn:isbn:1-931666-22-9 http://www.loc.gov/ead/ead.xsd"
xmlns:ns2="http://www.w3.org/1999/xlink"
xmlns="urn:isbn:1-931666-22-9"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>

产生想要的结果

<foo xmlns="urn:isbn:1-931666-22-9"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns:xlink="http://www.w3.org/1999/xlink"
     xsi:schemaLocation="urn:isbn:1-931666-22-9 http://www.loc.gov/ead/ead.xsd"
     audience="external"/>

【讨论】:

  • 谢谢!非常有帮助! omit-xml-declaration="yes" 对于生成格式良好的 HTML5 输出也很有用。
【解决方案2】:

您确实应该为此使用“身份模板”,并且您应该随时准备好它。使用该模板创建一个 XSLT,将其命名为“identity.xslt”,然后进入当前的 XSLT。假设要替换的命名空间的前缀为“bad”,而要替换的命名空间为“good”with,那么你只需要一个这样的模板(我在工作,所以请原谅格式;当我在家时,我会回到这个问题):...如果这在 XSLT 1.0 中不起作用,请使用匹配表达式,如 "*[namespace-uri() = 'urn :bad-namespace'",并按照 Dimitre 的说明以编程方式创建新元素。在 内,您确实需要递归地应用模板……但实际上,请阅读身份模板。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-11-27
    • 2012-08-16
    • 1970-01-01
    • 1970-01-01
    • 2016-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多