【问题标题】:Removing duplicates in xslt based on two different child node values根据两个不同的子节点值删除 xslt 中的重复项
【发布时间】:2019-08-20 07:55:55
【问题描述】:

我正在尝试为以下要求生成 XSLT。

我使用了基于 sequenceNumber |Type|Value 的 generate-id 和 Key,它正在删除 Items/Item 下的 Duplicate。

但不知道如何检查重复的 StateType 以及相同的 StateType 并仅删除同时满足这两个条件的 Item。

所以我想删除包含重复值的 StateType 重复值(基本上两者都在不同的父级下。)

<!-- language: lang-xml -->

    <Containers>
    <Container>
     <DetailContainer>
      <Items>
       <Item>
        <SequenceNumber>1</SequenceNumber>
        <Type>Property</Type>
        <Value>100</Value>
       </Item>
       <Item>
        <SequenceNumber>2</SequenceNumber>
        <Type>Insurance</Type>
        <Value>200</Value>
       </Item>
      </Items>
      <Property>
       <ID>1</ID>
       <Date>2019-03-12</Date>
      </Property>
     <DetailContainer>
     <State>
      <StateType>Current</StateType>
      <ID>1</ID>
      <Date>2019-03-12</Date>
     </State>
    </Container>
    <Container>
     <DetailContainer>
      <Items>
       <Item>
        <SequenceNumber>3</SequenceNumber>
        <Type>Property</Type>
        <Value>600</Value>
       </Item>
       <Item>
        <SequenceNumber>4</SequenceNumber>
        <Type>Insurance</Type>
        <Value>500</Value>
       </Item>
      </Items>
      <Property>
       <ID>2</ID>
       <Date>2017-07-12</Date>
      </Property>
     </DetailContainer>
     <State>
      <StateType>Previous</StateType>
      <ID>1</ID>
      <Date>2019-03-12</Date>
     </State>
    </Container>
    <Container>
     <DetailContainer>
      <Items>
       <Item>
        <SequenceNumber>1</SequenceNumber>
        <Type>Property</Type>
        <Value>100</Value>
       </Item>
       <Item>
        <SequenceNumber>2</SequenceNumber>
        <Type>Insurance</Type>
        <Value>200</Value>
       </Item>
      </Items>
      <Property>
       <ID>2</ID>
       <Date>2019-03-12</Date>
      </Property>
     </DetailContainer>
     <State>
      <StateType>Current</StateType>
      <ID>1</ID>
      <Date>2019-03-12</Date>
     </State>
    </Container>
    </Containers>

预期输出 -

    <Containers>
    <Container>
     <DetailContainer>
      <Items>
       <Item>
        <SequenceNumber>1</SequenceNumber>
        <Type>Property</Type>
        <Value>100</Value>
       </Item>
       <Item>
        <SequenceNumber>2</SequenceNumber>
        <Type>Insurance</Type>
        <Value>200</Value>
       </Item>
      </Items>
      <Property>
       <ID>1</ID>
       <Date>2019-03-12</Date>
      </Property>
     </DetailContainer>
     <State>
      <StateType>Current</StateType>
      <ID>1</ID>
      <Date>2019-03-12</Date>
     </State>
    </Container>
    <Container>
     <DetailContainer>
      <Items>
       <Item>
        <SequenceNumber>3</SequenceNumber>
        <Type>Property</Type>
        <Value>600</Value>
       </Item>
       <Item>
        <SequenceNumber>4</SequenceNumber>
        <Type>Insurance</Type>
        <Value>500</Value>
       </Item>
      </Items>
      <Property>
       <ID>2</ID>
       <Date>2017-07-12</Date>
      </Property>
    </DetailContainer>
     <State>
      <StateType>Previous</StateType>
      <ID>1</ID>
      <Date>2019-03-12</Date>
     </State>
    </Container>
    <Container>
     <DetailContainer>
      <Items>

      </Items>
      <Property>
       <ID>2</ID>
       <Date>2019-03-12</Date>
      </Property>
     </DetailContainer>
     <State>
      <StateType>Current</StateType>
      <ID>1</ID>
      <Date>2019-03-12</Date>
     </State>
    </Container>
    </Containers>



------------------------------------------------------------------------

删除重复项的代码 -

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:key name="ItemDup" match="Item" use="concat(SequenceNumber,'|',Type,'|', Value)" />

<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-template select="node()|@*" />
</xsl:copy>
</xsl:template>

<xsl:template match="Item[generate-id(key('ItemDup',concat(SequenceNumber,'|',Type,'|', Value))[1])]">
<xsl:copy>
<xsl:apply-template/>
</xsl:copy>
</xsl:template>

<xsl:template match="Item">
</xsl:template>
</xsl:stylesheet>

【问题讨论】:

  • 对于分组问题,XSLT 1.0 和 2.0 的解决方案将有所不同,所以请说出哪个版本。也请展示您的最佳尝试,然后我们可以看到您已经知道的内容以及您遇到的问题。
  • @Michael Kay,我已经粘贴了 XSLT(1.0) 用于删除重复项。但是我坚持如何为 State 定义另一个键并根据这个键删除 Item。
  • Item元素作为上下文节点,StateType元素的相对路径将是parent::Items/parent::DetailContainer/parent::Container/child::State/child::StateType或缩写../../../State/StateType
  • 请将您的示例修正为格式正确的 XML 文档。
  • 删除重复的 可以基于上面提到的两个不同的复合键吗?

标签: xml xslt xml-parsing grouping


【解决方案1】:

我想这就是你所要求的。您正在尝试删除基于concat(SequenceNumber,'|', Type,'|', Value)的重复项

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


    <xsl:key name="ItemDup" match="Item" use="concat(SequenceNumber,'|', Type,'|', Value)" />

    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="Item[generate-id() != generate-id(key('ItemDup', concat(SequenceNumber, '|', Type, '|', Value))[1])]" />

</xsl:stylesheet>

【讨论】:

  • 当State/StateType也是重复的时候,我想根据concat(SequenceNumber ,'|',Type,'|',Value)删除重复的,否则不要删除。
猜你喜欢
  • 1970-01-01
  • 2016-11-09
  • 1970-01-01
  • 2017-06-15
  • 1970-01-01
  • 2021-08-15
  • 2017-07-11
  • 2011-10-07
相关资源
最近更新 更多