XSLT只选择行集中的最后一个版本元素 [英] XSLT select only last version element in rowset

查看:160
本文介绍了XSLT只选择行集中的最后一个版本元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

My xml是:

 < RowSet> 
< Row>
< msg_id> 1< / msg_id>
< doc_id> 1< / doc_id>
< doc_version> 1< / doc_version>
< / Row>
< Row>
< msg_id> 2< / msg_id>
< doc_id> 1< / doc_id>
< doc_version> 2< / doc_version>
< / Row>
< Row>
< msg_id> 3< / msg_id>
< doc_id> 1< / doc_id>
< doc_version> 3< / doc_version>
< / Row>
< Row>
< msg_id> 4< / msg_id>
< doc_id> 2< / doc_id>
< doc_version> 1< / doc_version>
< / Row>
< RowSet>

我需要做的是:

如果存在具有相同 doc_id 的行,则只需要选择大于 doc_version 数字的节点。



预期输出:

 < RowSet> 
< Row>
< msg_id> 3< / msg_id>
< doc_id> 1< / doc_id>
< doc_version> 3< / doc_version>
< / Row>
< Row>
< msg_id> 4< / msg_id>
< doc_id> 2< / doc_id>
< doc_version> 1< / doc_version>
< / Row>
< RowSet>

可能会有帮助: msg_id 是独一无二的,所以对于相同的 doc_id 来说,大于 msg_id 的行保存最后一个 doc_version

解决方案

与其他答案不同,

>

 < xsl:stylesheet version =1.0xmlns:xsl =http://www.w3.org/1999/XSL/变换> 
< xsl:output omit-xml-declaration =yesindent =yes/>
< xsl:strip-space elements =*/>

< xsl:key name =kRowByDocIdmatch =Rowuse =doc_id/>

< xsl:template match =/ *>
Row [generate-id()= generate-id(key('kRowByDocId',doc_id)[1])]/>
< / xsl:template>

< xsl:template match =Row>
< xsl:for-each select =key('kRowByDocId',doc_id)>
< xsl:sort select =doc_versiondata-type =numberorder =descending/>

< xsl:if test =position()= 1>< xsl:copy-of select =。/>< / xsl:if>
< / xsl:for-each>
< / xsl:template>
< / xsl:stylesheet>

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

 < RowSet> 
< Row>
< msg_id> 1< / msg_id>
< doc_id> 1< / doc_id>
< doc_version> 1< / doc_version>
< / Row>
< Row>
< msg_id> 2< / msg_id>
< doc_id> 1< / doc_id>
< doc_version> 2< / doc_version>
< / Row>
< Row>
< msg_id> 3< / msg_id>
< doc_id> 1< / doc_id>
< doc_version> 3< / doc_version>
< / Row>
< Row>
< msg_id> 4< / msg_id>
< doc_id> 2< / doc_id>
< doc_version> 1< / doc_version>
< / Row>
< / RowSet>

想要的,正确的结果会产生:
$ b

 < Row> 
< msg_id> 3< / msg_id>
< doc_id> 1< / doc_id>
< doc_version> 3< / doc_version>
< / Row>
< Row>
< msg_id> 4< / msg_id>
< doc_id> 2< / doc_id>
< doc_version> 1< / doc_version>
< / Row>

解释


  1. 正确使用 Muenchian分组方法来找到属于每个不同组的一个项目。

  2. 正确使用 排序 以查找组中的最大项目。


  3. 正确使用 key() 函数 - 用于选择给定组中的所有项目。



My xml is:

<RowSet>
  <Row>
     <msg_id>1</msg_id>
     <doc_id>1</doc_id>
     <doc_version>1</doc_version>
  </Row>
  <Row>
     <msg_id>2</msg_id>
     <doc_id>1</doc_id>
     <doc_version>2</doc_version>
  </Row>
    <Row>
     <msg_id>3</msg_id>
     <doc_id>1</doc_id>
     <doc_version>3</doc_version>
  </Row>
      <Row>
     <msg_id>4</msg_id>
     <doc_id>2</doc_id>
     <doc_version>1</doc_version>
  </Row>
  <RowSet>

What I need to do:

If there are Rows with the same doc_id, I need to select only node with the bigger doc_version number.

Expected output:

 <RowSet>
    <Row>
     <msg_id>3</msg_id>
     <doc_id>1</doc_id>
     <doc_version>3</doc_version>
   </Row>
      <Row>
     <msg_id>4</msg_id>
     <doc_id>2</doc_id>
     <doc_version>1</doc_version>
  </Row>
  <RowSet>

May be it might be helpful: msg_id is unique, so Row with bigger msg_id for the same doc_id hold the last doc_version.

解决方案

This transformation works, unlike some other answers:

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

 <xsl:key name="kRowByDocId" match="Row" use="doc_id"/>

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

 <xsl:template match="Row">
     <xsl:for-each select="key('kRowByDocId',doc_id)">
      <xsl:sort select="doc_version" data-type="number" order="descending"/>

      <xsl:if test="position() = 1"><xsl:copy-of select="."/></xsl:if>
     </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

When applied on the provided XML document:

<RowSet>
    <Row>
        <msg_id>1</msg_id>
        <doc_id>1</doc_id>
        <doc_version>1</doc_version>
    </Row>
    <Row>
        <msg_id>2</msg_id>
        <doc_id>1</doc_id>
        <doc_version>2</doc_version>
    </Row>
    <Row>
        <msg_id>3</msg_id>
        <doc_id>1</doc_id>
        <doc_version>3</doc_version>
    </Row>
    <Row>
        <msg_id>4</msg_id>
        <doc_id>2</doc_id>
        <doc_version>1</doc_version>
    </Row>
</RowSet>

the wanted, correct result is produced:

<Row>
   <msg_id>3</msg_id>
   <doc_id>1</doc_id>
   <doc_version>3</doc_version>
</Row>
<Row>
   <msg_id>4</msg_id>
   <doc_id>2</doc_id>
   <doc_version>1</doc_version>
</Row>

Explanation:

  1. Proper use of the Muenchian Grouping method for finding one item belonging to each different group.

  2. Proper use of sorting for finding a maximum item in a group.

  3. Proper use of the key() function -- for selecting all items in a given group.

这篇关于XSLT只选择行集中的最后一个版本元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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