How to remove default namespace and keep the rest of namespaces using XSLT?

时光毁灭记忆、已成空白 提交于 2019-12-10 09:02:26

问题


I have a XML file having default namespace and empty namespaces which need to be removed, while keeping the rest of namespaces.

Input:

<prefix:request xmlns:prefix="urn1" xmlns:foo2="urn2" xmlns="urn1">
<element1 xmlns="">version1</element1>
<element2 xsi:type="prefix:requestA" xmlns=""/>
...
</element1>
</prefix:request>

Expected output:

<prefix:request xmlns:prefix="urn1" xmlns:foo2="urn2">
<element1>version1</element1>
<element2 xsi:type="prefix:requestA"/>
...
</element1>
</prefix:request>

XSLT sample for removing namespaces will filter out all namespaces, including the prefix. Any idea how to solve this particular case?


回答1:


This short transformation:

<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:copy-of select="@*|namespace::*[name()]"/>
       <xsl:apply-templates select="node()"/>
     </xsl:element>
 </xsl:template>
</xsl:stylesheet>

when applied on the (severely malformed and having to be corrected) provided XML-like input:

<prefix:request xmlns:xsi="Undefined !!!"
xmlns:prefix="urn1" xmlns:foo2="urn2"
xmlns="urn1">
    <element1 xmlns="">version1</element1>
    <element2 xsi:type="prefix:requestA" xmlns=""/> ...  
</prefix:request>

produces the wanted, correct result:

<prefix:request xmlns:prefix="urn1" xmlns:xsi="Undefined !!!" xmlns:foo2="urn2">
   <element1>version1</element1>
   <element2 xsi:type="prefix:requestA"/> ...  
</prefix:request>



回答2:


Well the snippet that you have posted is not even well-formed XML so it is hard to tell what you want to achieve, as the second closing </element1> does not have any corresponding opening tag and as the prefix xsi is used but never declared.

However assuming you have

<prefix:request xmlns:prefix="urn1" xmlns:foo2="urn2" xmlns="urn1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<element1 xmlns="">version1</element1>
<element2 xsi:type="prefix:requestA" xmlns=""/>

</prefix:request>

then the stylesheet

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="1.0">

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

  <xsl:template match="@* | text() | comment() | processing-instruction()">
    <xsl:copy/>
  </xsl:template>

</xsl:stylesheet>

when applied with Saxon 6.5.5 will output

<?xml version="1.0" encoding="utf-8"?><prefix:request xmlns:prefix="urn1" xmlns:foo2="urn2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<element1>version1</element1>
<element2 xsi:type="prefix:requestA"/>

</prefix:request>


来源:https://stackoverflow.com/questions/7023533/how-to-remove-default-namespace-and-keep-the-rest-of-namespaces-using-xslt

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