XSLT:将命名空间添加到根元素

时间:2010-04-21 21:19:54

标签: xslt namespaces

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

输入文件:

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

感谢您的任何建议!

2 个答案:

答案 0 :(得分:10)

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

答案 1 :(得分:1)

你应该真的使用“身份模板”,你应该随时掌握它。使用该模板创建一个XSLT,将其命名为“identity.xslt”,然后调用当前的XSLT。假设要替换的命名空间的前缀为“bad”,对于要用替换它的的那个“好”,那么你只需要一个这样的模板(我正在工作) ,请原谅格式化;当我在家时,我会回到这里:)...如果在XSLT 1.0中不起作用,请使用匹配表达式,如“* [namespace-uri()='urn :bad-namespace'“,并按照Dimitre的指令以编程方式创建新元素。在内部,你真的需要递归地应用模板......但实际上,请阅读身份模板。