需要 XSLT 转换来删除重复元素 - 按属性排序
我有一段糟糕的 XML,需要通过 BizTalk 进行处理,并且我已设法将其规范化为下面的示例。我不是 XSLT 忍者,但在 Web 和 VS2010 调试器之间,我可以找到解决 XSL 的方法。
我现在需要一个聪明的 XSLT 来“清除”重复的元素并只保留最新的元素,这由 ValidFromDate 属性中的日期决定。
ValidFromDate 属性是 XSD:Date 类型。
<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>
转换后,我只想保留这些行:
<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 排序脚本,但我觉得没有一个能带我走向正确的方向。
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.
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.
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>
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
Xslt 1.0 解决此问题的最佳解决方案是使用 Muenchian 分组。 (假设元素已按 ValidFromDate 属性排序)以下样式表应该可以解决问题:
这是我针对示例 Xml 运行它时得到的结果:
The optimal solution for this problem with Xslt 1.0 would be to use Muenchian grouping. (Given that the elements are already sorted by the ValidFromDate attribute) the following stylesheet should do the trick:
Here is the result I got when running it against your sample Xml:
比 @lwburk 稍微简单和简短的 XSLT 1.0 解决方案:
当此转换应用于提供的 XML 文档时:
生成所需的正确结果< /强>:
A slightly simpler and shorter XSLT 1.0 solution than that of @lwburk:
when this transformation is applied on the provided XML document:
the wanted, correct result is produced:
以下样式表会生成正确的结果,而不依赖于输入顺序:
输出:
请注意,结果与您列出的所需输出略有不同,因为
C_1
是实际上是最新的C
元素(即输入尚未已排序)。通过依赖初始排序顺序(并盲目遵循列出的预期输出),现有答案实际上是不正确的。解释:
xsl:key
通过name()
对所有/SomeData/*
进行分组,for -each
选择每个组中的第一个项目@ValidFromDate
排序The following stylesheet produces the correct result without any reliance on the input order:
Output:
Note that the result is slightly different than what you listed as the desired output, because
C_1
is actually the latestC
element (i.e. the input is not already sorted). By relying on an initial sort order (and blindly following the listed expected output) the existing answers are actually incorrect.Explanation:
xsl:key
groups all/SomeData/*
byname()
for-each
selects the first item in each group@ValidFromDate
基于
@ValidFromDate
订单:XSLT:
应用于:
产生:
Based on
@ValidFromDate
order:XSLT:
applied on:
produces:
根据Pawel的回答,我做了以下修改,产生了相同的结果:
如果它们每次都产生相同的结果,我喜欢这个,因为它更干净一点。
Based on Pawel's answer, I made the following modification, which produces the same result:
If they produce the same result every time, I like this because it's a little cleaner.
XLST 2.0 解决方案不依赖输入顺序。
XLST 2.0 solution without relying on input order.