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はユニークなので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. それぞれの異なるグループに属する 1 つのアイテムを見つけるためのMuenchian Groupingメソッドの適切な使用。

  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 に答える