2

我有一个如下所示的 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 来执行此操作。过滤器列表中的值是动态的。任何人都可以帮助解决这个问题。

4

2 回答 2

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>

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

于 2012-12-20T15:39:23.420 回答
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>

这将删除其名称与同一元素的 FilterListd2p1:Application中包含的过滤器之一不匹配的任何子代(包括元素本身,如果没有)。d2p1:Applicationd2p1:FilterList<d2p1:Filter>FilterList</d2p1:Filter>

即使d2p1:Application您的文档中有多个元素,并且每个元素都由它自己控制FilterList(我假设您提供的 XML 是文档的片段而不是完整的示例,我认为缺少名称空间声明,这也将起作用)。

于 2012-12-20T16:36:43.617 回答