根据其他子值删除具有相同子值的不同父节点中的重复节点

时间:2018-06-09 12:40:48

标签: xslt

我正在努力用XSLT完成这项任务:

我需要从XML中删除重复的节点,但它与通常的不同,因为这些节点可以在不同的父节点中,我不能删除第一次出现但是有优先顺序规则。

这是我的INPUT

<?xml version="1.0" encoding="UTF-8"?>
<xml>
<Collection>
<AddedType>
<Type>
    <Name>BBBBBBB</Name>
    <Status>On</Status>
    <Version>2</Version>
    <Iteration>3</Iteration>
</Type>
<Type>
    <Name>AAAAAAA</Name>
    <Status>Off</Status>
    <Version>3</Version>
    <Iteration>0</Iteration>
</Type>
<Type>
    <Name>CCCCCCC</Name>
    <Status>On</Status>
    <Version>0</Version>
    <Iteration>1</Iteration>
</Type>
<Type>
    <Name>BBBBBBB</Name>
    <Status>Off</Status>
    <Version>4</Version>
    <Iteration>0</Iteration>
</Type>
</AddedType>
<ChangedType>
<Type>
    <Name>BBBBBBB</Name>
    <Status>On</Status>
    <Version>7</Version>
    <Iteration>2</Iteration>
</Type>
</ChangedType>
<UnchangedType>
<Type>
    <Name>AAAAAAA</Name>
    <Status>On</Status>
    <Version>2</Version>
    <Iteration>0</Iteration>
</Type>
</UnChangedType>
<DeletedType>
<Type>
    <Name>XXXXXX</Name>
    <Status>On</Status>
    <Version>5</Version>
    <Iteration>1</Iteration>
</Type>
</DeletedType>
</Collection>
</xml>

所需的输出

<?xml version="1.0" encoding="UTF-8"?>
<xml>
<Collection>
<AddedType>
<Type>
    <Name>CCCCCCC</Name>
    <Status>On</Status>
    <Version>0</Version>
    <Iteration>1</Iteration>
</Type>
</AddedType>
<ChangedType>
<Type>
    <Name>BBBBBBB</Name>
    <Status>On</Status>
    <Version>7</Version>
    <Iteration>2</Iteration>
</Type>
</ChangedType>
<UnchangedType>
<Type>
    <Name>AAAAAAA</Name>
    <Status>On</Status>
    <Version>2</Version>
    <Iteration>0</Iteration>
</Type>
</UnChangedType>
<DeletedType>
<Type>
    <Name>XXXXXX</Name>
    <Status>On</Status>
    <Version>5</Version>
    <Iteration>1</Iteration>
</Type>
</DeletedType>
</Collection>
</xml>

类型节点可以在 AddedType ChangedType UnChangedType DeletedType

状态只能开启关闭 开启&gt; 关闭

版本是数字,整数

迭代是数字,整数

正如您在上面的示例中所看到的,我需要在OUTPUT中只有1个 Type 节点出现并具有相同的 Name 值,并且它应该是根据以下规则具有更高优先级的一个:

选择保留哪一个的完整密钥是(状态)。(版本)。(迭代)示例: Off.5.1&lt; Off.5.8&lt; Off.7.5&lt; On.0.0&lt; On.3.9

任何帮助都将非常感激

1 个答案:

答案 0 :(得分:2)

我认为您希望按Type对所有Name元素进行分组,然后按各种排序键/优先级对每个组进行排序,以降序排序顺序输出第一个元素,由其原始父级包装名:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    version="3.0">

  <xsl:mode on-no-match="shallow-copy"/>

  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="Collection">
      <xsl:copy>
          <xsl:for-each-group select="*/Type" group-by="Name">
              <xsl:for-each select="current-group()">
                  <xsl:sort select="Status" order="descending"/>
                  <xsl:sort select="xs:integer(Version)" order="descending"/>
                  <xsl:sort select="xs:integer(Iteration)" order="descending"/>
                  <xsl:if test="position() = 1">
                      <xsl:element name="{name(..)}">
                        <xsl:copy-of select="."/>
                      </xsl:element>
                  </xsl:if>
              </xsl:for-each>
          </xsl:for-each-group>
      </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/pPqsHTk我得到了结果

<xml>
   <Collection>
      <ChangedType>
         <Type>
            <Name>BBBBBBB</Name>
            <Status>On</Status>
            <Version>7</Version>
            <Iteration>2</Iteration>
         </Type>
      </ChangedType>
      <UnchangedType>
         <Type>
            <Name>AAAAAAA</Name>
            <Status>On</Status>
            <Version>2</Version>
            <Iteration>0</Iteration>
         </Type>
      </UnchangedType>
      <AddedType>
         <Type>
            <Name>CCCCCCC</Name>
            <Status>On</Status>
            <Version>0</Version>
            <Iteration>1</Iteration>
         </Type>
      </AddedType>
      <DeletedType>
         <Type>
            <Name>XXXXXX</Name>
            <Status>On</Status>
            <Version>5</Version>
            <Iteration>1</Iteration>
         </Type>
      </DeletedType>
   </Collection>
</xml>

它似乎包含您在所需输出中显示的元素,缺少您在那里显示的顺序。我不确定是什么决定了这个订单所以你需要解释一下如果代码需要调整而你自己不能这样做。