2014-12-03 112 views
0

嗨,要删除XML重复的节点如何使用XSLT 1.0

请帮我从xml.Condition移除重复的节点,除去重复的节点是相当复杂的。

条件1:在根据policyKey节点的每个政策节点i必须检查policyNbr和PolicyFormCode /代码和policyEffectiveDt和策略ID 是在所有的策略节点相同的,如果它们是相同的,我有只保留具有sourceSystemCd策略节点/代码='SCBP'出现在它中。

条件2:如果在上述条件policyNbr和PolicyFormCode/code和policyEffectiveDt和policyID中有任何不同的值,我需要显示所有的策略节点。

输入XML: 条件1:

<?xml version="1.0" encoding="utf-8"?> 
<policies> 
    <!-- policy 1--> 
    <policy> 
     <policyKey> 
      <policyNbr>4567</policyNbr> 
      <policyEffectiveDt>2014-11-14</policyEffectiveDt> 
      <policyFormCd> 
       <code>669</code> 
      </policyFormCd> 
     </policyKey> 
     <transactionSplitTrans> 
      <sourceSystemCd> 
       <code>ARA</code> 
      </sourceSystemCd> 
     </transactionSplitTrans> 
    </policy> 
    <!-- second --> 
    <policy> 
     <policyKey> 
      <policyNbr>1234</policyNbr> 
      <policyID>115774001</policyID> 
      <policyEffectiveDt>2014-11-11</policyEffectiveDt> 
      <policyFormCd> 
       <code>660</code> 
      </policyFormCd> 
     </policyKey> 
     <transactionSplitTrans> 
      <sourceSystemCd> 
       <code>ARAR</code> 
      </sourceSystemCd> 
     </transactionSplitTrans> 
    </policy> 
    <!-- third --> 
    <policy> 
     <policyKey> 
      <policyEffectiveDt>2014-11-14</policyEffectiveDt> 
      <policyFormCd> 
       <code>660</code> 
      </policyFormCd> 
      <policyID>115774001</policyID> 
      <policyNbr>1234</policyNbr> 
     </policyKey> 
     <transactionSplitTrans> 
      <sourceSystemCd> 
       <code>SCBP</code> 
      </sourceSystemCd> 
     </transactionSplitTrans> 
    </policy> 
</policies> 

Expexted输出:

<policies> 
    <!-- policy 1--> 
<policy> 
    <policyKey> 
     <policyNbr>4567</policyNbr> 
     <policyEffectiveDt>2014-11-14</policyEffectiveDt> 
     <policyFormCd> 
      <code>669</code> 
     </policyFormCd> 
    </policyKey> 
    <transactionSplitTrans> 
     <sourceSystemCd> 
      <code>ARA</code> 
     </sourceSystemCd> 
    </transactionSplitTrans> 
</policy> 
<!-- third --> 
<policy> 
    <policyKey> 
     <policyEffectiveDt>2014-11-14</policyEffectiveDt> 
     <policyFormCd> 
      <code>660</code> 
     </policyFormCd> 
     <policyID>115774001</policyID> 
     <policyNbr>1234</policyNbr> 
    </policyKey> 
    <transactionSplitTrans> 
     <sourceSystemCd> 
      <code>SCBP</code> 
     </sourceSystemCd> 
    </transactionSplitTrans> 
</policy> 
</policies> 

条件2:显示所有三个policyNodes

+0

所以,如果有没有重复,你要保持一个没有政策ID? – Mike 2014-12-03 05:43:13

+0

您是否熟悉[Muenchian分组](http://www.jenitennison.com/xslt/grouping/muenchian.html)? – 2014-12-03 06:52:55

回答

1
<xsl:template match="/policies/policy"> 
<xsl:choose> 
    <xsl:when test="./policyKey/policyID"> 
     <xsl:copy-of select='.'/> 
    </xsl:when> 
    <xsl:otherwise> 
     <xsl:variable name='currNumber' select="number(policyKey/policyNbr)"/> 
     <xsl:variable name="currCode" select="policyKey/policyFormCd/code"/> 
     <xsl:if test="count(../policy/policyKey[number(policyNbr)=$currNumber and policyFormCd/code=$currCode and policyID]) = 0"> 
      <xsl:copy-of select='.'/> 
     </xsl:if> 
    </xsl:otherwise> 
</xsl:choose> 
</xsl:template> 

这应该工作。如果政策有一个ID,然后复制它。如果没有,并且没有与ID相匹配的一个,那么也复制它。 (可能会更短,但这应该足够清楚)。测试。

+0

添加了对策略代码的检查。数字与数字(policyNbr)进行比较以处理不同的格式。 – Mike 2014-12-03 07:56:47

+0

更改示例以包含代码检查。 – Mike 2014-12-03 08:02:28

+0

上面的代码中我们有“number(something)”的地方,替换为:“substring(concat('0000000000000000',something),string-length(something)+1,16)”。这使用前导零填充到16个字节,然后取最右边的16个字符。 如果某些十六进制值是大写和小写(例如7E707和7e707),则必须将其包含在transform()语句中。 Yuck,但这是你的XSL。 – Mike 2014-12-03 10:25:22

0

请替换上面的XSLT以下部分,并尝试...

<xsl:variable name='currNumber' select="translate(policyKey/policyNbr,'0*','')"/> 


<xsl:if test="count(../policy/policyKey[translate(policyNbr,'0*','')=$currNumber and policyFormCd/code=$currCode and policyID]) = 0"> 
+0

xslt没有正则表达式,所以你不能指定* leading *零。上面的翻译将用零值替换全零。 – Mike 2014-12-04 07:20:01