Remove a specific xmlns from root element of xml

筅森魡賤 提交于 2019-12-05 13:11:03

Please give this a try:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" exclude-result-prefixes="xsi"
>

  <xsl:output omit-xml-declaration="yes" indent="yes"/>
  <xsl:strip-space elements="*"/>

  <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(. = 'http://www.w3.org/2001/XMLSchema-instance')]" />
      <xsl:apply-templates select="@*|node()"/>
    </xsl:element>
  </xsl:template>

  <xsl:template match="@xsi:noNamespaceSchemaLocation"/>

</xsl:stylesheet>

I have got two options:

XSLT1:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>
  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>
  <xsl:template match="@*[local-name(.)='noNamespaceSchemaLocation']"/>
</xsl:stylesheet>

Output1:

<?xml version="1.0" encoding="utf-8"?>
<addresses xmlns="http://www.test.org/xml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <address>
    <name>Joe Tester</name>
    <street>Baker street 5</street>
  </address>
</addresses>

XSLT2:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>

  <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:template match="@*[local-name(.)='noNamespaceSchemaLocation']"/>
</xsl:stylesheet>

Output2:

<?xml version="1.0" encoding="utf-8"?>
<addresses>
  <address>
    <name>Joe Tester</name>
    <street>Baker street 5</street>
  </address>
</addresses>
Ian Roberts

Your problem is that when copying an element node <xsl:copy> implicitly copies namespace nodes that are in scope at that point in the document. Try adding an extra template for element nodes to specifically exclude the xsi namespace:

<xsl:template match="*">
  <xsl:element name="{name()}" namespace="{namespace-uri()}">
    <xsl:copy-of select="namespace::*[not(name() = 'xsi')]" />
    <xsl:apply-templates select="@*|node()"/>
  </xsl:element>
</xsl:template>

If your xsl:stylesheet has an xmlns:xsi then you may also find you need to add exclude-result-prefixes="xsi" as suggested in this answer.

This should prevent the xsi namespace from appearing in the output if it is there solely because it was copied from the input, though the serialiser may re-introduce it if required to make the output well formed (i.e. if it needs to output an element or attribute in that namespace).

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!