2017-05-05 76 views
0

我想應用XSLT將我現有的XML轉換爲刪除未使用的名稱空間。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

[如何在XSLT 1.0中模仿copy-namespaces =「no」?](http://stackoverflow.com/q/9026224/2711488) – Holger

+1

請注意,未使用的名稱空間聲明是(或至少應該是)良性的。您的預期輸出在語義上與實際輸出相同。 –

+0

@Holger:這仍然不能清除未使用的名稱空間。 我知道這些聲明是良性的。但是,我正在改變一個現有的系統,而不想修改以前出現的結果。 – Krishna

回答

3

下載撒克遜給自己XSLT 2.0的好處,然後就去做

<xsl:copy-of select="/" copy-namespaces="no"/> 

它可以在XSLT 1.0進行,但它的複雜得多。

+0

這不能用默認的java xslt實現來完成嗎? – Krishna

+0

默認的Java XSLT實現僅支持XSLT 1.0,因此不支持copy-namespaces屬性 –

+0

謝謝,我將嘗試使用Saxon。 – Krishna