1

我的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是独一无二的,所以 Row 具有更大msg_id的相同doc_id保留最后一个doc_version

4

3 回答 3

1

与其他一些答案不同,这种转换有效

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

应用于提供的 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>

产生了想要的正确结果:

<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()功能 - 用于选择给定组中的所有项目。

于 2012-11-01T12:23:52.120 回答
0

XSLT 1.0 解决方案

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:key name="doc_id" match="RowSet/Row" use="doc_id"/>
    <xsl:template match="/">
        <xsl:for-each select="RowSet/Row[generate-id() = generate-id(key('doc_id',doc_id))]">
            <xsl:sort select="doc_id" data-type="number" order="ascending"/>

            <xsl:for-each select="../Row[doc_id = current()/doc_id]">
                <xsl:sort select="doc_version" data-type="number" order="descending"/>
                <xsl:if test="position() = 1">
                    // stuff
                </xsl:if>
            </xsl:for-each>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

逻辑是:

  • 获取每个唯一的文档 ID
  • 然后跳上一个级别并使用该 doc_id 遍历每个 doc_version
  • 取最高的doc_version
于 2012-11-01T11:28:15.657 回答
-1

尝试这个

 <xsl:for-each-group select="RowSet/RowSet" group-by="doc_id">
       <xsl:for-each select="current-group()">
       <xsl:sort select="doc_version" order="desending"/>
          <xsl:if test="position()=1">
                   // do it your stuff here
            </xsl:if>
        </xsl:for-each>
    </xsl:for-each-group>
于 2012-11-01T09:55:07.890 回答