【问题标题】:Remove duplicate nodes in different parents with same child value, based on other childs value根据其他子值删除具有相同子值的不同父级中的重复节点
【发布时间】:2018-06-09 12:40:47
【问题描述】:

我正在努力使用 XSLT 完成这项工作:

我需要从 XML 中删除重复节点,但它与通常的不同,因为这些节点可能位于不同的父节点中,我不能只删除第一个出现的节点,但有一个优先级规则。

这是我的输入

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

Type节点可以在AddedType ChangedType UnChangedType DeletedType

Status只能是OnOffOn > Off

版本是数字、整数

迭代是数字,整数

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

选择保留哪一个的完整键是(状态).(版本).(迭代)示例:Off.5.1

任何帮助将不胜感激

【问题讨论】:

  • 您是否仅限于使用 xslt 或者您可以使用任何 oop 语言?
  • 不幸的是,我仅限于使用 XLST,否则我已经使用 xmltables 完成了此操作并稍后重建了 xml
  • 您是否使用 .net 框架的 XSLTCompiledTransform 来执行 xslt?
  • 我目前正在从命令行调用 Saxon
  • 您可以使用 saxon 框架添加扩展对象。然后您可以在 .net 代码中生成节点结构

标签: xslt


【解决方案1】:

我认为您希望将所有这些 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>

这似乎有你想要的输出中出现的元素,缺少你在那里显示的顺序。我不确定是什么决定了该顺序,因此您需要说明是否需要调整代码并且您自己不能这样做。

【讨论】:

  • 谢谢伙计,我真的需要研究 xslt > 1.0...关于类型的顺序并不重要,只是父级的顺序很重要,它是固定的(添加、更改、未更改、删除)但是我想我至少可以做到这一点:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-05-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-06
  • 2019-10-25
相关资源
最近更新 更多