Remove a specific xmlns from root element of xml

南楼画角 提交于 2019-12-22 07:21:53

问题


I'm trying to make a transformation for an XML document but i cannot find a solution since i do not know XSLT. I have the XML document:

<?xml version="1.0" encoding="UTF-8"?>
<addresses xmlns="http://www.test.org/xml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:noNamespaceSchemaLocation='http://whatever/test.xsd'>

  <address>
    <name>Joe Tester</name>
    <street>Baker street 5</street>
  </address>

</addresses>

and i want to produce:

<?xml version="1.0" encoding="UTF-8"?>
<addresses xmlns="http://www.test.org/xml">

  <address>
    <name>Joe Tester</name>
    <street>Baker street 5</street>
  </address>

</addresses>

(Consider that xsi:noNamespaceSchemaLocation="..." has already excluded using another XSLT before this one).

Can someone help me find a solution?

The XSLT used to eliminate the xsi:noNamespaceSchemaLocation is:

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

<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="@xsi:noNamespaceSchemaLocation"/>

</xsl:stylesheet>

回答1:


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>



回答2:


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>



回答3:


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



来源:https://stackoverflow.com/questions/14188119/remove-a-specific-xmlns-from-root-element-of-xml

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