2013-04-08 140 views
0

我得到了一個XML,我轉換成另一個XML,但在翻譯之後,我得到了一些我想刪除的具有空名稱空間聲明(xmlns="")的元素。刪除元素中的空名稱空間聲明

其次我還想要在InterChangeHead元素中聲明xmlns:xsi

輸入XML

<?xml version="1.0" encoding="UTF-8"?> 
<PostenInterchange type="tag"> 
    <heInterchangeType>PostenInterchange</heInterchangeType> 
    <heVersion>1.4-rev3</heVersion> 
    <heTestindicator>1</heTestindicator> 
    <InterChangeHead type="tag"> 
     <heVersion>1</heVersion> 
     <heSenderid>SENDID</heSenderid> 
     <heRecipientid>RECIPID</heRecipientid> 
     <heXmlnsxsi>"http://www.w3.org/2001/XMLSchema-instance"</heXmlnsxsi> 
     <heXmlns>"posten.xsd"</heXmlns> 
     <Shipment type="tag"> 
      <heShipmenttype>IMP</heShipmenttype> 
      <Shipper type="tag"> 
       <name>Shipper</name> 
      </Shipper> 
      <Consignee type="tag"> 
       <name>Consignee</name> 
      </Consignee> 
      <GoodsData type="tag"> 
       <heSequencenumber>2</heSequencenumber> 
       <GrossWeight>0.000</GrossWeight> 
       <NetWeight>0.660</NetWeight> 
      </GoodsData> 
     </Shipment> 
    </InterChangeHead> 
</PostenInterchange> 

CURRENT XSLT

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" exclude-result-prefixes="xs fn"> 
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 

    <!-- Identity template --> 
    <xsl:template match="@*|node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()" /> 
     </xsl:copy> 
    </xsl:template> 

    <!-- Copy local names --> 
    <xsl:template match="*"> 
     <xsl:element name="{name()}"> 
      <xsl:apply-templates select="@*|node()" /> 
     </xsl:element> 
    </xsl:template> 

    <!-- Rename elements beginning with "he" to elements without the "he" --> 
    <xsl:template match="node()"> 
     <xsl:choose> 
      <xsl:when test="substring(local-name(), 1, 2) = 'he'"> 
       <xsl:element name="{substring(local-name(), 3)}"> 
        <xsl:apply-templates select="@*|node()" /> 
       </xsl:element> 
      </xsl:when> 
      <xsl:otherwise> 
       <xsl:copy> 
        <xsl:apply-templates select="@*|node()" /> 
       </xsl:copy> 
      </xsl:otherwise> 
     </xsl:choose> 
    </xsl:template> 

    <!-- Correct InterChangeHead element --> 
    <xsl:template match="InterChangeHead"> 
     <xsl:element name="InterChangeHead" namespace="posten.xsd">  
      <!-- Copy childs --> 
      <xsl:apply-templates select="child::node()" /> 
     </xsl:element> 
    </xsl:template> 

    <!-- Remove type attribute --> 
    <xsl:template match="@type"/> 

    <!-- Remove unnecessary elements --> 
    <xsl:template match="heXmlnsxsi" /> 
    <xsl:template match="heXmlns" /> 
</xsl:stylesheet> 

電流輸出

<?xml version="1.0" encoding="UTF-8"?> 
<PostenInterchange> 
    <InterchangeType>PostenInterchange</InterchangeType> 
    <Version>1.4-rev3</Version> 
    <Testindicator>1</Testindicator> 
    <InterChangeHead xmlns="posten.xsd"> 
     <Version xmlns="">1</Version> 
     <Senderid xmlns="">SENDID</Senderid> 
     <Recipientid xmlns="">RECIPID</Recipientid> 
     <Shipment xmlns=""> 
      <Shipmenttype>IMP</Shipmenttype> 
      <Shipper> 
       <name>Shipper</name> 
      </Shipper> 
      <Consignee> 
       <name>Consignee</name> 
      </Consignee> 
      <GoodsData> 
       <Sequencenumber>2</Sequencenumber> 
       <GrossWeight>0.000</GrossWeight> 
       <NetWeight>0.660</NetWeight> 
      </GoodsData> 
     </Shipment> 
    </InterChangeHead> 
</PostenInterchange> 

所需的輸出

<?xml version="1.0" encoding="UTF-8"?> 
<PostenInterchange> 
    <InterchangeType>PostenInterchange</InterchangeType> 
    <Version>1.4-rev3</Version> 
    <Testindicator>1</Testindicator> 
    <InterChangeHead xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="posten.xsd" > 
     <Version>1</Version> 
     <Senderid>SENDID</Senderid> 
     <Recipientid>RECIPID</Recipientid> 
     <Shipment> 
      <Shipmenttype>IMP</Shipmenttype> 
      <Shipper> 
       <name>Shipper</name> 
      </Shipper> 
      <Consignee> 
       <name>Consignee</name> 
      </Consignee> 
      <GoodsData> 
       <Sequencenumber>2</Sequencenumber> 
       <GrossWeight>0.000</GrossWeight> 
       <NetWeight>0.660</NetWeight> 
      </GoodsData> 
     </Shipment> 
    </InterChangeHead> 
</PostenInterchange> 

誰能幫助我的最後一位?我加了一個模板,因爲我認爲這將刪除空的命名空間聲明:

<!-- Copy local names --> 
<xsl:template match="*"> 
    <xsl:element name="{name()}"> 
     <xsl:apply-templates select="@*|node()" /> 
    </xsl:element> 
</xsl:template> 

回答

1

請記住,xmlns="..."聲明爲其所連接的元素及其所有後代設置默認名稱空間,除非由樹下方的另一個xmlns="..."進行反轉。因此,在您希望的輸出中,<InterChangeHead xmlns="posten.xsd" >下的所有後代元素也位於posten.xsd名稱空間中,並且您的模板需要反映此情況。由於您使用XSLT 2.0,你可以使用條件的XPath表達式的一部分,這樣做很容易:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 

    <!-- Copy elements, fixing up names and namespaces as required --> 
    <xsl:template match="*"> 
     <xsl:element name="{if(substring(local-name(), 1, 2) = 'he') 
          then substring(local-name(), 3) else local-name()}" 
        namespace="{if(ancestor-or-self::InterChangeHead) 
           then 'posten.xsd' else ''}"> 
      <xsl:apply-templates select="@*|node()" /> 
     </xsl:element> 
    </xsl:template> 

    <!-- specific template for InterChangeHead to add the (unused) xsi 
     namespace declaration --> 
    <xsl:template match="InterChangeHead"> 
     <InterChangeHead xmlns="posten.xsd" 
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
     <xsl:apply-templates select="@*|node()" /> 
     </InterChangeHead> 
    </xsl:template> 

    <xsl:template match="@* | text()"> 
     <xsl:copy-of select="." /> 
    </xsl:template> 

    <!-- Remove type attribute --> 
    <xsl:template match="@type"/> 

    <!-- Remove unnecessary elements --> 
    <xsl:template match="heXmlnsxsi" /> 
    <xsl:template match="heXmlns" /> 
</xsl:stylesheet> 

我添加了一個特定的模板聲明對InterChangeHeadxsi命名空間,雖然我不知道爲什麼有必要包含該聲明,因爲它在輸出XML文檔中的任何地方都不使用。如果事實證明沒有必要,您可以簡單地刪除<xsl:template match="InterChangeHead">,因爲匹配*的模板也將處理InterChangeHead,正確設置名稱空間。

+0

爲什麼template''需要? – 2013-04-08 11:58:22

+0

@MarkVeenstra我從技術上來說並不是因爲你正在處理的XML輸入沒有任何屬性(除了你無視的'標籤'之外)以及該模板在'text()節點與默認相同。習慣,我認爲,我總是傾向於從身份模板開始...... – 2013-04-08 12:01:55

0

您需要更改每個元素節點的命名空間,所以更改模板

<!-- Correct InterChangeHead element --> 
<xsl:template match="InterChangeHead"> 
    <xsl:element name="InterChangeHead" namespace="posten.xsd">  
     <!-- Copy childs --> 
     <xsl:apply-templates select="child::node()" /> 
    </xsl:element> 
</xsl:template> 

<!-- Correct InterChangeHead element and descendants --> 
<xsl:template match="InterChangeHead | InterChangeHead//*"> 
    <xsl:element name="{local-name()}" namespace="posten.xsd">  
     <!-- Copy childs --> 
     <xsl:apply-templates select="@* | node()" /> 
    </xsl:element> 
</xsl:template> 

下面是一個簡化代碼的完整樣式表:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" exclude-result-prefixes="xs fn"> 
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 

    <!-- Identity template --> 
    <xsl:template match="@*|node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()" /> 
     </xsl:copy> 
    </xsl:template> 

    <!-- Correct InterChangeHead element --> 
    <xsl:template match="InterChangeHead | InterChangeHead//*"> 
     <xsl:element name="{local-name()}" namespace="posten.xsd">  
      <!-- Copy childs --> 
      <xsl:apply-templates select="@* | node()" /> 
     </xsl:element> 
    </xsl:template> 

    <!-- Rename elements beginning with "he" to elements without the "he" --> 
    <xsl:template match="InterChangeHead//*[substring(local-name(), 1, 2) = 'he']" priority="5"> 
       <xsl:element name="{substring(local-name(), 3)}" namespace="posten.xsd"> 
        <xsl:apply-templates select="@*|node()" /> 
       </xsl:element> 
    </xsl:template> 

    <!-- Remove type attribute --> 
    <xsl:template match="@type"/> 

    <!-- Remove unnecessary elements --> 
    <xsl:template match="heXmlnsxsi" priority="6"/> 
    <xsl:template match="heXmlns" priority="6"/> 
</xsl:stylesheet> 
相關問題