XSLT:从XML中删除未使用的命名空间

时间:2017-05-05 09:18:43

标签: xml xslt java-8 cxf xalan

我想应用XSLT来转换现有的XML以删除未使用的命名空间。

示例XML:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Session xmlns="http://www.cloud.com/prod/v1.5" xmlns:ovf="http://schemas.dmtf.org/ovf/envelope/1" 
xmlns:vssd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_VirtualSystemSettingData" 
xmlns:common="http://schemas.dmtf.org/wbem/wscim/1/common" 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData" 
xmlns:vmw="http://www.cloud.com/schema/ovf" 
xmlns:ovfenv="http://schemas.dmtf.org/ovf/environment/1" 
xmlns:vmext="http://www.cloud.com/prod/extension/v1.5" 
xmlns:ns9="http://www.cloud.com/prod/networkservice/1.0" 
xmlns:ns10="http://www.cloud.com/prod/networkservice/common/1.0" 
xmlns:ns11="http://www.cloud.com/prod/networkservice/ipam/1.0" 
xmlns:ns12="http://www.cloud.com/prod/versions" 
org="Development" roles="vApp Author" user="kchaitanya" 
userId="urn:prod:user:0dc14413-74ce-4a20-8908-0e2fd1da6160" href="https://x.x.x.x/api/session" 
type="application/vnd.cloud.prod.session+xml">
    <Link rel="remove" href="https://x.x.x.x/api/session"/>
    <Link rel="down" href="https://x.x.x.x/api/admin/" type="application/vnd.cloud.admin.prod+xml"/>
    <Link rel="entityResolver" href="https://x.x.x.x/api/entity/" type="application/vnd.cloud.prod.entity+xml"/>
    <Link rel="down:extensibility" href="https://x.x.x.x/api/extensibility" type="application/vnd.cloud.prod.apiextensibility+xml"/>
    <ovf:Info>My Ovf Info</ovf:Info>
    <vmext:Extension>
        <vssd:Info> 2000 </vssd:Info>
    </vmext:Extension>
</Session>

使用的XSLT:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output 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="{local-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 version="1.0" encoding="UTF-8" standalone="yes"?>
<Session xmlns="http://www.cloud.com/prod/v1.5" xmlns:ovf="http://schemas.dmtf.org/ovf/envelope/1" 
xmlns:vssd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_VirtualSystemSettingData" 
xmlns:vmext="http://www.cloud.com/prod/extension/v1.5" 
org="Development" roles="vApp Author" user="kchaitanya" 
userId="urn:prod:user:0dc14413-74ce-4a20-8908-0e2fd1da6160" href="https://x.x.x.x/api/session" 
type="application/vnd.cloud.prod.session+xml">
    <Link rel="remove" href="https://x.x.x.x/api/session"/>
    <Link rel="down" href="https://x.x.x.x/api/admin/" type="application/vnd.cloud.admin.prod+xml"/>
    <Link rel="entityResolver" href="https://x.x.x.x/api/entity/" type="application/vnd.cloud.prod.entity+xml"/>
    <Link rel="down:extensibility" href="https://x.x.x.x/api/extensibility" type="application/vnd.cloud.prod.apiextensibility+xml"/>
    <ovf:Info>My Ovf Info</ovf:Info>
    <vmext:Extension>
        <vssd:Info> 2000 </vssd:Info>
    </vmext:Extension>
</Session>

但实际输出:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns0:Session xmlns:ns0="http://www.vmware.com/vcloud/v1.5" xmlns="http://www.cloud.com/prod/v1.5"
org="Development" roles="vApp Author" user="kchaitanya" 
userId="urn:prod:user:0dc14413-74ce-4a20-8908-0e2fd1da6160" href="https://x.x.x.x/api/session" 
type="application/vnd.cloud.prod.session+xml">
    <ns1:Link xmlns:ns1="http://www.vmware.com/vcloud/v1.5" rel="remove" href="https://x.x.x.x/api/session"/>
    <ns2:Link xmlns:ns2="http://www.vmware.com/vcloud/v1.5" rel="down" href="https://x.x.x.x/api/admin/" type="application/vnd.cloud.admin.prod+xml"/>
    <ns3:Link xmlns:ns3="http://www.vmware.com/vcloud/v1.5" rel="entityResolver" href="https://x.x.x.x/api/entity/" type="application/vnd.cloud.prod.entity+xml"/>
    <ns4:Link xmlns:ns4="http://www.vmware.com/vcloud/v1.5" rel="down:extensibility" href="https://x.x.x.x/api/extensibility" type="application/vnd.cloud.prod.apiextensibility+xml"/>
    <ns5:Info xmlns:ns5="http://schemas.dmtf.org/ovf/envelope/1" >My Ovf Info</ns5:Info>
    <ns6:Extension xmlns:ns6="http://www.cloud.com/prod/extension/v1.5" >
        <ns7:Info xmlns:ns7="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_VirtualSystemSettingData" > 2000 </ns7:Info>
    </ns6:Extension>
</ns0:Session>

我正在使用java 1.8.121和CXF 3.1.11(org.apache.cxf.interceptor.XSLTOutInterceptor)来转换XML。默认情况下,使用的XSLT包是“com.sun.org.apache.xalan.internal.xsltc”。 我使用了apache-xalan 2.7.1,结果相同。

我无法在线测试,因为java代码的输出和在线xslt测试(例如:http://xsltransform.net/)的输出不同。

任何人都可以建议,正确的方法或XSLT来实现我想要做的事情吗?

1 个答案:

答案 0 :(得分:3)

下载Saxon以获得XSLT 2.0的好处,然后再做

markertype

可以在XSLT 1.0中完成,但它要复杂得多。