XSLT从XML过滤元素

时间:2012-12-20 15:11:06

标签: xml xslt

我有如下的XML。

<d2p1:Application> 
 <d2p1:Identifier>0001482022534</d2p1:Identifier> 
 <d2p1:Channel>Web</d2p1:Channel> 
 <d2p1:Type>Change</d2p1:Type> 
 <d2p1:Status>Received</d2p1:Status> 
 <d2p1:Value>Received</d2p1:Value> 
 <d2p1:FilterList> 
  <d2p1:Filter>Channel</d2p1:Filter> 
  <d2p1:Filter>Type</d2p1:Filter> 
  <d2p1:Filter>Value</d2p1:Filter> 
 </d2p1:FilterList> 
</d2p1:Application>

期望的输出:

<d2p1:Application> 
 <d2p1:Channel>Web</d2p1:Channel> 
 <d2p1:Type>Change</d2p1:Type> 
 <d2p1:Value>Received</d2p1:Value> 
</d2p1:Application>

我想要的输出是从XML中删除不在<FilterList>.中的元素我需要XSLT才能执行此操作。 “过滤器”列表中的值是动态的。任何人都可以帮忙解决这个问题。

2 个答案:

答案 0 :(得分:2)

一种方法可能是使用密钥来查找“过滤器”值

<xsl:key name="Filter" match="d2p1:Filter" use="." />

然后,您可以扩展XSLT标识转换以包含一个模板,该模板匹配键不返回任何内容的元素。

<xsl:template match="d2p1:Application/*[not(key('Filter', local-name()))]" />

这是完整的XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:d2p1="d2p1">
   <xsl:output method="xml" indent="yes"/>
   <xsl:key name="Filter" match="d2p1:Filter" use="." />

   <xsl:template match="d2p1:Application/*[not(key('Filter', local-name()))]" />

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

当应用于您的示例XML时(假设它包含前缀d2p1的名称空间声明),输出以下内容

<d2p1:Application xmlns:d2p1="d2p1">
   <d2p1:Channel>Web</d2p1:Channel>
   <d2p1:Type>Change</d2p1:Type>
   <d2p1:Value>Received</d2p1:Value>
</d2p1:Application>

请注意,您必须相应地更改命名空间。

答案 1 :(得分:0)

如果您使用身份模板复制所有内容然后覆盖要删除的内容的常规方法,则问题就变成了如何识别要删除的内容。 <怎么样

<!-- NB - fix the xmlns:d2p1 to match the document -->
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
          xmlns:d2p1="urn:d2p1">

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

  <xsl:template match="d2p1:Application/*[
      not(local-name() = ../d2p1:FilterList/d2p1:Filter)]" />
</xsl:stylesheet>

这将删除d2p1:Application的所有子项,其名称与同一d2p1:Application元素的FilterList中包含的某个过滤器不匹配(包括d2p1:FilterList元素本身,如果没有{ {1}})。

即使文档中有多个<d2p1:Filter>FilterList</d2p1:Filter>元素,每个元素都由它自己的d2p1:Application控制,这也会起作用(我假设缺少名称空间声明,你提供的XML是你文档的一个片段,而不是一个完整的例子。)