需要XSLT转换以删除重复的元素-按属性排序 [英] Need XSLT transform to remove duplicate elements - sorted by an attribute

查看:84
本文介绍了需要XSLT转换以删除重复的元素-按属性排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个很糟糕的XML,需要通过BizTalk处理,并且已经设法将其标准化到下面的示例中.我不是XSLT忍者,但在Web和VS2010调试器之间,我可以找到解决XSL的方法.

I have a terrible piece of XML that I need to process through BizTalk, and I have managed to normalise it into this example below. I am no XSLT ninja, but between the web and the VS2010 debugger, I can find my way around XSL.

我现在需要一个聪明的XSLT来清除"重复的元素,并仅保留最新的元素,这取决于 ValidFromDate 属性中的日期.

I now need a clever bit of XSLT to "weed out" the duplicate elements and only keep the latest ones, as decided by the date in the ValidFromDate attribute.

ValidFromDate属性为XSD:Date类型.

The ValidFromDate attribute is of the XSD:Date type.

<SomeData>
  <A ValidFromDate="2011-12-01">A_1</A>
  <A ValidFromDate="2012-01-19">A_2</A>
  <B CalidFromDate="2011-12-03">B_1</B>
  <B ValidFromDate="2012-01-17">B_2</B>
  <B ValidFromDate="2012-01-19">B_3</B>
  <C ValidFromDate="2012-01-20">C_1</C>
  <C ValidFromDate="2011-01-20">C_2</C>
</SomeData>

转换后,我只保留以下几行:

After a transformation I'd like to only keep these lines:

<SomeData>
  <A ValidFromDate="2012-01-19">A_2</A>
  <B ValidFromDate="2012-01-19">B_3</B>
  <C ValidFromDate="2012-01-20">C_1</C>
</SomeData>

关于如何将XSL组合在一起的任何线索?我已经清空了互联网,试图寻找解决方案,并且尝试了很多聪明的XSL排序脚本,但是没有一个能带我正确的方向.

Any clues as to how I put that XSL together? I've emptied the internet trying to look for a solution, and I have tried a lot of clever XSL sorting scripts, but none I felt took me in the right direction.

推荐答案

比@lwburk的解决方案更简单,更短的XSLT 1.0解决方案:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:key name="kName" match="*/*" use="name()"/>

 <xsl:template match="/">
  <xsl:apply-templates select=
   "*/*[generate-id()
       =
        generate-id(key('kName', name())[1])
       ]
   "/>
 </xsl:template>

 <xsl:template match="*/*">
  <xsl:for-each select="key('kName', name())">
   <xsl:sort select="@ValidFromDate" order="descending"/>
   <xsl:if test="position() = 1">
    <xsl:copy-of select="."/>
   </xsl:if>
  </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

当此转换应用于提供的XML文档时:

<SomeData>
    <A ValidFromDate="2011-12-01">A_1</A>
    <A ValidFromDate="2012-01-19">A_2</A>
    <B CalidFromDate="2011-12-03">B_1</B>
    <B ValidFromDate="2012-01-17">B_2</B>
    <B ValidFromDate="2012-01-19">B_3</B>
    <C ValidFromDate="2012-01-20">C_1</C>
    <C ValidFromDate="2011-01-20">C_2</C>
</SomeData>

产生了所需的正确结果:

<A ValidFromDate="2012-01-19">A_2</A>
<B ValidFromDate="2012-01-19">B_3</B>
<C ValidFromDate="2012-01-20">C_1</C>

这篇关于需要XSLT转换以删除重复的元素-按属性排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆