1

他の「ユーザー」との親子関係を持つ「ユーザー」の単一のフラットリストがあります。ユーザーの「親」は承認者 ID です。XSLT 2.0 を使用できるように、このリストをソートして、リスト内で親よりも子が優先されないようにする必要があります。入力 xml の例:

<userList>
    <user>
        <userID>4</userID>
        <approverID>2</approverID>
    </user>
    <user>
        <userID>5</userID>
        <approverID>2</approverID>
    </user>
    <user>
        <userID>3</userID>
        <approverID>1</approverID>
    </user>
    <user>
        <userID>2</userID>
        <approverID>1</approverID>
    </user>
    <user>
        <userID>1</userID>
        <approverID>10</approverID>
    </user>
    <user>
        <userID>6</userID>
        <approverID>7</approverID>
    </user>
    <user>
        <userID>7</userID>
        <approverID>10</approverID>
    </user>
</userList>


1 { 2 {4,5} , 3}
7 {6 }のような親子構造になります (表示する最善の方法はわかりません) 。

出力 XML は次のようになります。

<userList>
    <user>
        <userID>1</userID>
        <approverID>10</userID>
    </user>
    <user>
        <userID>2</userID>
        <approverID>1</approverID>
    </user>
    <user>
        <userID>3</userID>
        <approverID>1</approverID>
    </user>
    <user>
        <userID>4</userID>
        <approverID>2</approverID>
    </user>
    <user>
        <userID>5</userID>
        <approverID>2</approverID>
    </user>
    <user>
        <userID>7</userID>
        <approverID>10</approverID>
    </user>
    <user>
        <userID>6</userID>
        <approverID>7</approverID>
    </user>
</userList>

唯一の要件は、子ユーザーが親の前に来ないことですが、それ以外はとにかくソートできます。これを再帰的に行うこともできると思いますが、XSLT のような関数型プログラミング言語ではそれが最善の選択肢ではないことはわかっています。

4

1 に答える 1

1

入力と出力の間にいくつかの不一致があるようです (そして、出力は 2 つの場所で要件に違反していると思います) が、これが目的だと思います。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes" omit-xml-declaration="yes" />
  <xsl:key name="kUserByApprover" match="user" use="approverID"/>
  <xsl:key name="kUserById" match="user" use="userID"/>

  <xsl:template match="@* | node()" name="copy">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="userList">
    <xsl:copy>
      <!-- Process users whose approver is not present -->
      <xsl:apply-templates select="user[not(key('kUserById', approverID))]" />
    </xsl:copy>
  </xsl:template>

  <xsl:template match="user">
    <xsl:call-template name="copy" />
    <!-- Process child users -->
    <xsl:apply-templates select="key('kUserByApprover', userID)" />
  </xsl:template>
</xsl:stylesheet>

サンプル入力で実行すると、結果は次のようになります。

<userList>
  <user>
    <userID>1</userID>
    <approverID>10</approverID>
  </user>
  <user>
    <userID>3</userID>
    <approverID>1</approverID>
  </user>
  <user>
    <userID>2</userID>
    <approverID>1</approverID>
  </user>
  <user>
    <userID>4</userID>
    <approverID>2</approverID>
  </user>
  <user>
    <userID>5</userID>
    <approverID>2</approverID>
  </user>
  <user>
    <userID>7</userID>
    <approverID>10</approverID>
  </user>
  <user>
    <userID>6</userID>
    <approverID>7</approverID>
  </user>
</userList>
于 2013-10-16T04:14:43.100 に答える