根据搜索条件删除部分

时间:2013-07-22 08:47:17

标签: xslt xslt-1.0

我的要求是删除一个关键字标签,其中@guid只与@relationObj<roleCode tc=32><roleCode tc=31>的关系<roleCode tc=8>匹配。 上述逻辑也适用于@relationObj,该@relationObj应与只有<roleCode tc=32><roleCode tc=31><roleCode tc=8>的{​​{1}}之一匹配。

基本上我想通过查找@guid属于@relationObj@relationObj<roleCode tc=32>的其他关键字代码来搜索<roleCode tc=31><roleCode tc=8> 。如果此条件为真,请删除此部分。

以下是XML:

<Relations>
<Relation guid="abcd1234" relationObj="1234">
    <roleCode tc="20"/>
</Relation>
<Relation guid="xyz123" relationObj="1111">
    <roleCode tc="32"/>
</Relation>

<Relation guid="def123" relationObj="2222">
    <roleCode tc="31"/>
</Relation>

<Relation guid="1111" relationObj="2222">
    <roleCode tc="98"/>
</Relation>

<Relation guid="jkl123" relationObj="3333">
    <roleCode tc="8"/>
</Relation>

<Relation guid="2222" relationObj="1234">
    <roleCode tc="100"/>
</Relation>
</Relations>

我尝试创建三个变量来为模板中的每个@relationObj提取<roleCode tc>[32,31 and 8]。然后将@objectId@relationObj与这三个变量进行比较。但问题是,变量在迭代时遇到另一个<Relation>标记时会更新为空值。

从xml上面我应该在转换后得到xml以下。

<Relations>
<Relation guid="abcd1234" relationObj="1234">
    <roleCode tc="20"/>
</Relation>
<Relation guid="xyz123" relationObj="1111">
    <roleCode tc="32"/>
</Relation>

<Relation guid="def123" relationObj="2222">
    <roleCode tc="31"/>
</Relation>
<Relation guid="jkl123" relationObj="3333">
    <roleCode tc="8"/>
</Relation>
<Relation guid="2222" relationObj="1234">
    <roleCode tc="100"/>
</Relation>
</Relations>

如果您观察到,{guid =“1111”relationObj =“2222”]的<Relation>标签将被删除。因为@guid和@relationObj都属于roleCodes之一--32,31或8。

您能不能让我知道在不更新新变量的情况下保存变量值的最佳方法是什么?还是有任何更好的方法我可以做到这一点。 谢谢你的时间。

1 个答案:

答案 0 :(得分:1)

我会通过定义一个来解决这个问题,它可以提取特定roleCode的所有relationObj值,然后使用该键选择{{ 1}}要排除的元素。如果我正确理解您的要求,那么我认为这应该有效:

Relation

当一方是节点集时,相等测试在XPath中的工作方式是,如果集合中的任何节点与该值匹配,则测试为真。因此

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

  <xsl:key name="roleCodeByRelObj" match="roleCode" use="../@relationObj" />

  <!-- copy input to output except where more specific template applies -->
  <xsl:template match="@*|node()">
    <xsl:copy><xsl:apply-templates select="@*|node()" /></xsl:copy>
  </xsl:template>

  <!-- ignore any Relation whose guid and relationObj match the relationObj of a
       Relation whose roleCode/@tc is 8, 31 or 32 (not necessarily the same
       matching Relation in both cases) -->
  <xsl:template match="Relation[
       (
         (key('roleCodeByRelObj', @guid)/@tc = '8') or
         (key('roleCodeByRelObj', @guid)/@tc = '31') or
         (key('roleCodeByRelObj', @guid)/@tc = '32')
       )
     and
       (
         (key('roleCodeByRelObj', @relationObj)/@tc = '8') or
         (key('roleCodeByRelObj', @relationObj)/@tc = '31') or
         (key('roleCodeByRelObj', @relationObj)/@tc = '32')
       )
    ]" />

</xsl:stylesheet>

key('roleCodeByRelObj', @guid)/@tc = '31' 为“2222”时,您会从关键函数(guidroleCode)返回两个tc=31元素,并且整体测试成功,因为其中一个匹配目标值。