XSL - 如何从源 xml 中删除未使用的命名空间? [英] XSL - How to remove unused namespaces from source xml?

查看:28
本文介绍了XSL - 如何从源 xml 中删除未使用的命名空间?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含很多未使用的命名空间的 xml,如下所示:

I have an xml with a lot of unused namespaces, like this:

<?xml version="1.0" encoding="UTF-8"?>
<ns1:Envelope xmlns:ns1="http://www.a.com" xmlns:ns2="http://www.b.com" xmlns:ns3="http://www.c.com" xmlns:ns4="http://www.d.com">
    <ns1:Body>
        <ns2:a>
            <ns2:b>data1</ns2:b>
            <ns2:c>data2</ns2:c>
        </ns2:a>
    </ns1:Body>
</ns1:Envelope> 

我想删除未使用的名称空间,而不必在 xslt 中指定要删除/维护的名称空间.结果xml应该是这样的:

I would like to remove the unused namespaces without having to specify in the xslt which ones to remove/maintain. The result xml should be this:

<?xml version="1.0" encoding="UTF-8"?>
<ns1:Envelope xmlns:ns1="http://www.a.com" xmlns:ns2="http://www.b.com">
    <ns1:Body>
        <ns2:a>
            <ns2:b>data1</ns2:b>
            <ns2:c>data2</ns2:c>
        </ns2:a>
    </ns1:Body>
</ns1:Envelope> 

我在谷歌上搜索了很多,但没有找到解决这个特定问题的方法.有没有?

I've googled a lot but haven't found a solution to this particular issue. Is there any?

谢谢.

PS:不是 100% 肯定,但我认为它应该适用于 XSL 1.0.

PS: Not 100% sure but I think it should be for XSL 1.0.

推荐答案

与@Martin-Honnen 的回答不同,这个解决方案产生了完全想要的结果 -- 必要的命名空间节点保持在它们所在的位置并且不会向下移动.

Unlike the answer of @Martin-Honnen, this solution produces exactly the desired result -- the necessary namespace nodes remain where they are and are not moved down.

此外,此解决方案正确处理命名空间中的属性:

<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="node()|@*" priority="-2">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
 </xsl:template>

 <xsl:template match="*">
  <xsl:element name="{name()}" namespace="{namespace-uri()}">
   <xsl:variable name="vtheElem" select="."/>

   <xsl:for-each select="namespace::*">
     <xsl:variable name="vPrefix" select="name()"/>

     <xsl:if test=
      "$vtheElem/descendant::*
              [(namespace-uri()=current()
             and 
              substring-before(name(),':') = $vPrefix)
             or
              @*[substring-before(name(),':') = $vPrefix]
              ]
      ">
      <xsl:copy-of select="."/>
     </xsl:if>
   </xsl:for-each>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:element>
 </xsl:template>
</xsl:stylesheet>

当此转换应用于以下 XML 文档时(提供的带有添加命名空间属性的 XML 文档):

when this transformation is applied on the following XML document (the provided XML document with an added namespaced attribute):

<ns1:Envelope xmlns:ns1="http://www.a.com" xmlns:ns2="http://www.b.com" xmlns:ns3="http://www.c.com" xmlns:ns4="http://www.d.com">
    <ns1:Body ns2:x="1">
        <ns2:a>
            <ns2:b>data1</ns2:b>
            <ns2:c>data2</ns2:c>
        </ns2:a>
    </ns1:Body>
</ns1:Envelope>

产生了所需的正确结果:

<ns1:Envelope xmlns:ns1="http://www.a.com" xmlns:ns2="http://www.b.com">
   <ns1:Body ns2:x="1">
      <ns2:a>
         <ns2:b>data1</ns2:b>
         <ns2:c>data2</ns2:c>
      </ns2:a>
   </ns1:Body>
</ns1:Envelope>

这篇关于XSL - 如何从源 xml 中删除未使用的命名空间?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆