使用XSLT从XML中提取信息时无法摆脱名称空间

时间:2012-10-29 14:14:46

标签: xml xslt xml-namespaces

我在使用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要从上面的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之后收到的回复: 响应包含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>

请帮帮我。

提前致谢。

3 个答案:

答案 0 :(得分: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>

答案 1 :(得分:2)

如果您使用xsl:copy,则可以创建上下文节点的副本,如果元素表示您创建了具有相同名称的元素,并且名称由命名空间和本地名称组成。 copy-namespaces="no"仅帮助不复制范围命名空间中的任何其他名称空间,但它不会更改要复制的元素的名称。因此,在您的情况下,您想要的是将元素从某个名称空间转换为具有相同本地名称但没有名称空间的元素,即

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

答案 2 :(得分:1)

xsl:copy将包含绑定到该元素的名称空间。 copy-namespaces="no"只会从文档中排除未被复制的上下文元素中使用的无关名称空间。

如果要创建未绑定到输出中命名空间的元素(或属性),则需要使用xsl:element和使用xsl:attribute的新属性重新构建元素他们的local-name()为@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>