1

我的要求是删除与 Relation 的where或or only@guid之一匹配的 Relation 标签。上述逻辑也适用于应该与 Relation 的where或or only 之一匹配的情况。@relationObj<roleCode tc=32><roleCode tc=31><roleCode tc=8>@relationObj@relationObj<roleCode tc=32><roleCode tc=31><roleCode tc=8>

基本上我想搜索@guid@relationObj查找@relationObj属于<roleCode tc=32>or <roleCode tc=31>or的其他关系标签<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>

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

您能否让我知道在不更新新变量的情况下将值保存在变量中的最佳方法是什么?或者有什么更好的方法可以实现这一点。谢谢你的时间。

4

1 回答 1

1

我将通过定义一个来解决此问题,该键将允许您提取roleCode特定 的所有值relationObj,然后使用该键来选择Relation要排除的元素。如果我正确理解您的要求,那么我认为这应该可行:

<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>

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

key('roleCodeByRelObj', @guid)/@tc = '31'

when guidis "2222" 您从键函数 (和) 中roleCode返回两个元素,并且整体测试成功,因为其中一个与目标值匹配。tc=31tc=98

于 2013-07-22T09:53:18.733 回答