在一个XML上执行多个XSLT转换,每个转换都修改前一个转换的结果

时间:2017-06-20 09:44:10

标签: xml xslt

我需要删除命名空间并过滤掉下面响应中的所有GetShardHoldersResponseRecords并删除命名空间:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="http://schemas.blabla.com/service/ShardServiceResponse/1.0" xmlns:ns1="http://schemas.blabla.com/TYPELIB/1.0">
   <soapenv:Header/>
   <soapenv:Body>
     <GetShardHoldersResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tl="http://schemas.blabla.com/TYPELIB/1.0" xmlns:ns1="http://schemas.blabla.com/service/ShardServiceResponse/1.0">
         <ns1:Header>
            <tl:MsgId>myId</tl:MsgId>
         </ns1:Header>
         <ns1:GetShardHoldersResponseRecord>
            <ns1:ShardHolder>
               <tl:ShardHolderNo>5443137000478556</tl:ShardHolderNo>
               <tl:Shard>
                  <tl:ShardNo>5443132000143888</tl:ShardNo>
               </tl:Shard>
               <tl:Shard>
                  <tl:ShardNo>5443132000143889</tl:ShardNo>
               </tl:Shard>
            </ns1:ShardHolder>
         </ns1:GetShardHoldersResponseRecord>
      </GetShardHoldersResponse>
   </soapenv:Body>
</soapenv:Envelope>

我想要一个只包含responseRecords并删除名称空间的结果:

<GetShardHoldersResponseRecord>
            <ShardHolder>
               <ShardHolderNo>5443137000478556</ShardHolderNo>
               <Shard>
                  <ShardNo>5443132000143888</ShardNo>
               </Shard>
               <Shard>
                  <ShardNo>5443132000143889</ShardNo>
               </Shard>
            </ShardHolder>
         </GetShardHoldersResponseRecord>
      </GetShardHoldersResponse>

要删除命名空间,我知道我们可以:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:tl="http://schemas.blabla.com/TYPELIB/1.0" xmlns:ns1="http://schemas.blabla.com/service/ShardServiceResponse/1.0" >

 <xsl:output omit-xml-declaration="yes" indent="yes"/>



<!-- remove namespaces -->
<xsl:template match="*">
           <xsl:element name="{local-name()}" >
        <xsl:apply-templates/>
    </xsl:element>
</xsl:template>

</xsl:stylesheet>

要过滤掉GetShardHoldersResponse,我们可以使用以下内容:

 <xsl:template match="*">
<xsl:copy-of select="//GetShardHoldersResponse" />
<xsl:apply-templates/>
</xsl:template>

但我似乎无法将两个变换结合在一起。 如何在彼此之后组合两个这样的变换?

我一直用它来测试XSL:

http://www.utilities-online.info/xsltransformation/#.WUjXjxOGNN1

1 个答案:

答案 0 :(得分:1)

这应该做你想要的:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
  xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
  xmlns:ns1="http://schemas.blabla.com/service/ShardServiceResponse/1.0">

  <!--
  Omit these elements from the output, but apply the templates that match
  the child elements of the current element.
  -->
  <xsl:template match="soapenv:Envelope | soapenv:Body">
    <xsl:apply-templates/>
  </xsl:template>

  <!-- Omit these elements and their children from the output. -->
  <xsl:template match="soapenv:Header | ns1:Header"/>

  <!--
  For every other element, create a new element with the same local name
  in the empty namespace. Then apply the templates that match the child
  nodes of the current element.
  -->
  <xsl:template match="*">
    <xsl:element name="{local-name()}">
      <xsl:apply-templates select="@* | node()"/>
    </xsl:element>
  </xsl:template>

  <!--
  For every attribute node `@*` and text node `text()`, copy them into the
  output as is.
  -->
  <xsl:template match="@* | text()">
    <xsl:copy/>
  </xsl:template>

</xsl:stylesheet>