2012-10-29 43 views
1

我一直在使用XSLT從XML抽取信息時遇到問題。命名空間也出現在輸出中,這是不可接受的。使用XSLT從XML抽取信息時無法擺脫名稱空間

我從另一個系統收到的XML

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> 
    <soap:Body> 
     <ns1:DeptResponse xmlns:ns1="http://samplecomp.com" xmlns="http://mycomp.org"> 
      <Department> 
       <Building bid="b_1579"> 
       <DeptName>Sports</DeptName> 
       <DeptHead> 
        <Person pid="123"> 
         <Name>David Shephard</Name> 
         <Address> 
          <Street>Test</Street> 
          <State code="18">Georgia</State>    
         </Address>    
        </Person> 
       </DeptHead> 
       <DeptYear>1925</DeptYear> 
      </Department> 
     </ns1:DeptResponse> 
    </soap:Body> 
</soap:Envelope> 

我的XSL到etract從上面的XML所需的信息:

<xsl:stylesheet version="2.0"  
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  
    xmlns:ns1="http://samplecomp.com" 
    xmlns:dept="http://mycomp.org" 
    exclude-result-prefixes="ns1 xsl dept"> 

    <xsl:template match="/">   
     <xsl:apply-templates select="//dept:Person"/>  
    </xsl:template> 
    <xsl:template match="@*|node()">   
     <xsl:copy copy-namespaces="no" >    
      <xsl:apply-templates select="@*|node()"/>   
     </xsl:copy>  
    </xsl:template> 
</xsl:stylesheet> 

我XSL後收到的響應: contaitn一個的xmlns的響應: =「http://myccomp.org」,我想擺脫。我曾嘗試使用copy-namespaces =「no」但沒用。 :(

<Person xmlns="http://mycomp.org" pid="123"> 
    <Name>David Shephard</Name> 
    <Address> 
     <Street>Test</Street> 
     <State code="18">Georgia</State>    
    </Address> 
</Person> 

請幫幫我。

在此先感謝。

回答

1

xsl:copy將包括綁定到該元素的命名空間。copy-namespaces="no"只會排除該文件不屬於外來的命名空間用於正在複製的上下文元素

如果要創建未綁定到namesp的元素(或屬性)王牌在輸出中,你將需要重新構成使用xsl:element和使用xsl:attribute元素的新屬性與他們local-name()作爲@名稱:

<xsl:stylesheet version="2.0"  
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  
    xmlns:ns1="http://samplecomp.com" 
    xmlns:dept="http://mycomp.org" 
    exclude-result-prefixes="ns1 xsl dept"> 

    <xsl:template match="/">   
     <xsl:apply-templates select="//dept:Person"/>  
    </xsl:template> 

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

    <xsl:template match="@*">   
     <xsl:attribute name="{local-name()}" select="." /> 
    </xsl:template> 

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

</xsl:stylesheet> 
+0

非常感謝。有效。但我不明白爲什麼添加了文本()。 – user1760178

+0

我添加了'text()'以明確顯示模板正在處理通常由'node()'匹配的所有其他項目,現在有一個單獨的'*'模板。你可以放棄它,它仍然可以工作,因爲內置/默認模板會複製'text()'。 –

2
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  
    xmlns:ns1="http://samplecomp.com" 
    xmlns:dept="http://mycomp.org" 
    exclude-result-prefixes="ns1 xsl dept"> 
<xsl:output method="xml"/> 
    <xsl:template match="/">   
     <xsl:apply-templates select="//dept:Person"/>  
    </xsl:template> 
    <xsl:template match="*"> 
    <xsl:element name="{local-name()}"> 
     <xsl:apply-templates select="@*"/> 
     <xsl:apply-templates/> 
    </xsl:element> 
</xsl:template> 
<xsl:template match="@*"> 
    <xsl:attribute name="{local-name()}"> 
     <xsl:value-of select="."/> 
    </xsl:attribute> 
</xsl:template> 
</xsl:stylesheet> 
+0

非常感謝。有效。 – user1760178

2

那麼,如果你使用xsl:copy創建上下文節點的副本,在元素的情況下,這意味着您創建一個名稱相同的元素,名稱由名稱空間和本地名稱組成。 copy-namespaces="no"只有幫助不復制範圍名稱空間中的任何其他名稱,但它不會更改要複製的元素的名稱。所以在你的情況下,你想要的是將元素從某個命名空間轉換爲具有相同本地名稱但沒有命名空間的元素,即

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