如何使用xslt从源xml中删除命名空间和前缀属性?

时间:2012-05-24 10:01:35

标签: xml xslt

我有一个xml如下

<Publication xmlns:n1="http://www.w3.org/2001/XMLSchema-instance" n1:noNamespaceSchemaLocation="InformaKMSStructure.xsd"

我希望复制所有XML但不是 xmlns:n1 =“http://www.w3.org/2001/XMLSchema-instance”和n1:noNamespaceSchemaLocation =“InformaKMSStructure.xsd”

2 个答案:

答案 0 :(得分:2)

此转化

<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="*">
     <xsl:element name="{name()}" namespace="{namespace-uri()}">
       <xsl:apply-templates select="node()|@*"/>
     </xsl:element>
 </xsl:template>

 <xsl:template match="node()[not(self::*)]|@*">
  <xsl:copy/>
 </xsl:template>

 <xsl:template match=
 "@*[namespace-uri() = 'http://www.w3.org/2001/XMLSchema-instance']"/>
</xsl:stylesheet>

应用于以下XML文档(未提供!):

<Publication
 xmlns:n1="http://www.w3.org/2001/XMLSchema-instance"
 n1:noNamespaceSchemaLocation="InformaKMSStructure.xsd">
  <a x="y">
   <b/>
  </a>

  <c/>
</Publication>

会产生想要的正确结果:

<Publication>
   <a x="y">
      <b/>
   </a>
   <c/>
</Publication>

<强>解释

这遵循通常的覆盖身份规则的模式,但是身份规则被两个模板替换 - 一个匹配任何元素,第二个匹配任何其他节点或属性。

答案 1 :(得分:1)

n1:noNamespaceSchemaLocation =“InformaKMSStructure.xsd”是一个普通的属性,在XSLT中“删除”它的方法是避免复制它。如果你在XSLT中没有做任何事情,你就不会产生任何输出,所以如果你想避免输出某些内容,那么你需要找到输出它的代码并进行更改。您尚未向我们展示您的代码,因此我们无法告诉您如何更改它。

xmlns:n1 =“http://www.w3.org/2001/XMLSchema-instance”不同:在XPath数据模型中,它不被视为属性,而是被视为命名空间。实际上,此命名空间声明的存在会导致命名空间节点出现在其范围内的每个元素上。要摆脱这些名称空间,您需要了解哪些指令复制名称空间,哪些不复制名称空间。在XSLT 1.0中,xsl:copy和xsl:copy-of,当应用于元素时,复制所有元素的命名空间(无论是在该元素上还是在祖先上声明的)。为了阻止这种情况发生,在XSLT 2.0中你可以使用<xsl:copy copy-namespaces="no">,但在1.0中,唯一的选择是使用xsl:element而不是xsl:copy来重建元素。