4

非常に複雑なXSLT1.0クエリを作成する必要があります。

次のXMLファイルを考えると、複数のレポートに含まれる作成者のセットを取得するためのクエリが必要です。(たとえば、Antonio Rossiは、レポート1と2の両方に参加しているため)。

<reports>
  <report id="01">
    <titolo>
      I venti del Nord
    </titolo>
    <autori>
      <autore>
        Antonio Rossi
      </autore>
      <autore>
        Mario Verdi
      </autore>
    </autori>
    <versioni>
      <versione numero="1.0">
        <data>
          13-08-1980
        </data>
        <autore>
          Mario Verdi
        </autore>
        <commento>
          versione iniziale
        </commento>
      </versione>
      <versione numero="2.0">
        <data>
          14-08-1981
        </data>
        <autore>
          Antonio Rossi
        </autore>
        <commento>
          poche modifiche
        </commento>
      </versione>
    </versioni>
  </report>
  <report id="02">
    <titolo>
      Le pioggie del Nord
    </titolo>
    <autori>
      <autore>
        Antonio Rossi
      </autore>
      <autore>
        Luca Bianchi
      </autore>
    </autori>
    <versioni>
      <versione numero="1.0">
        <data>
          13-12-1991
        </data>
        <autore>
          Antonio Rossi
        </autore>
        <commento>
          versione iniziale
        </commento>
      </versione>
      <versione numero="2.0">
        <data>
          14-08-1992
        </data>
        <autore>
          Antonio Rossi
        </autore>
        <commento>
          modifiche al cap. 1
        </commento>
      </versione>
      <versione numero="3.0">
        <data>
          18-08-1992
        </data>
        <autore>
          Antonio Rossi
        </autore>
        <commento>
          Aggiunta intro.
        </commento>
      </versione>
      <versione numero="4.0">
        <data>
          13-01-1992
        </data>
        <autore>
          Luca Bianchi
        </autore>
        <commento>
          Modifiche sostanziali.
        </commento>
      </versione>
    </versioni>
  </report>
  <report id="03">
    <titolo>
      Precipitazioni nevose
    </titolo>
    <autori>
      <autore>
        Fabio Verdi
      </autore>
      <autore>
        Luca Bianchi
      </autore>
    </autori>
    <versioni>
      <versione numero="1.0">
        <data>
          11-01-1992
        </data>
        <autore>
          Fabio Verdi
        </autore>
        <commento>
          versione iniziale
        </commento>
      </versione>
      <versione numero="2.0">
        <data>
          13-01-1992
        </data>
        <autore>
          Luca Bianchi
        </autore>
        <commento>
          Aggiornato indice
        </commento>
      </versione>
    </versioni>
  </report>
</reports>
4

4 に答える 4

5

XPath 2.0を使用できる場合は、次を使用できます。

distinct-values(/reports/report/autori/autore[preceding::report/autori/autore = . or following::report/autori/autore = .])

入力XMLを使用すると、次の値が返されます。

Antonio Rossi
Luca Bianchi
于 2012-07-13T19:33:14.957 に答える
3

これはXPath1.0でも機能します。

//report//autore[text()=../../following-sibling::report//autore/text()]

次のノードのいずれかのノードautoreと等しいテキストコンテンツを持つすべてのノードも選択します。autorereport

または、短くするために、実際のxmlファイルに本当にトリッキーなものがない場合はこれでも機能するはずです。

//autore[text()=../../following-sibling::*//autore/text()]

編集:偶然に働いています。以下のコメントをご覧ください。

于 2012-07-13T19:45:23.297 に答える
3

I.この単純な(for-eachなし、変数なし)XSLT 1.0変換

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

  <xsl:key name="kAuthorByVal" match="autori/autore" use="normalize-space()"/>

  <xsl:template match="/">
   <xsl:copy-of select=
    "//autori/autore
                  [generate-id()
                  =
                   generate-id(key('kAuthorByVal', normalize-space())[1])
                   ]
                  [key('kAuthorByVal', normalize-space())[2]]"/>
  </xsl:template>
</xsl:stylesheet>

提供されたXMLドキュメントに適用した場合

<reports>
      <report id="01">
        <titolo>
          I venti del Nord
        </titolo>
        <autori>
          <autore>
            Antonio Rossi
          </autore>
          <autore>
            Mario Verdi
          </autore>
        </autori>
        <versioni>
          <versione numero="1.0">
            <data>
              13-08-1980
            </data>
            <autore>
              Mario Verdi
            </autore>
            <commento>
              versione iniziale
            </commento>
          </versione>
          <versione numero="2.0">
            <data>
              14-08-1981
            </data>
            <autore>
              Antonio Rossi
            </autore>
            <commento>
              poche modifiche
            </commento>
          </versione>
        </versioni>
      </report>
      <report id="02">
        <titolo>
          Le pioggie del Nord
        </titolo>
        <autori>
          <autore>
            Antonio Rossi
          </autore>
          <autore>
            Luca Bianchi
          </autore>
        </autori>
        <versioni>
          <versione numero="1.0">
            <data>
              13-12-1991
            </data>
            <autore>
              Antonio Rossi
            </autore>
            <commento>
              versione iniziale
            </commento>
          </versione>
          <versione numero="2.0">
            <data>
              14-08-1992
            </data>
            <autore>
              Antonio Rossi
            </autore>
            <commento>
              modifiche al cap. 1
            </commento>
          </versione>
          <versione numero="3.0">
            <data>
              18-08-1992
            </data>
            <autore>
              Antonio Rossi
            </autore>
            <commento>
              Aggiunta intro.
            </commento>
          </versione>
          <versione numero="4.0">
            <data>
              13-01-1992
            </data>
            <autore>
              Luca Bianchi
            </autore>
            <commento>
              Modifiche sostanziali.
            </commento>
          </versione>
        </versioni>
      </report>
      <report id="03">
        <titolo>
          Precipitazioni nevose
        </titolo>
        <autori>
          <autore>
            Fabio Verdi
          </autore>
          <autore>
            Luca Bianchi
          </autore>
        </autori>
        <versioni>
          <versione numero="1.0">
            <data>
              11-01-1992
            </data>
            <autore>
              Fabio Verdi
            </autore>
            <commento>
              versione iniziale
            </commento>
          </versione>
          <versione numero="2.0">
            <data>
              13-01-1992
            </data>
            <autore>
              Luca Bianchi
            </autore>
            <commento>
              Aggiornato indice
            </commento>
          </versione>
        </versioni>
      </report>
</reports>

必要な正しい結果を生成します。

<autore>
            Antonio Rossi
          </autore>
<autore>
            Luca Bianchi
          </autore>

説明

  1. 重要な観察事項はautori/autore、特定の文字列値を持つことは、内に複数回存在することはできないということreportです。これにより、ソリューションが大幅に簡素化されます(より複雑なソリューションについては、この回答の初期バージョンを参照してください)。この考慮事項は、この回答で提示されているすべてのソリューションで実質的に使用されています。

  2. autori/autore正規化された文字列値によってを識別するキーを定義します。したがってautori/autore、空白が異なるが同じ作成者を提示している2つは、同じ作成者のインスタンスとして扱われます。

  3. Muenchianグループ化方法を使用して、autori/autoreそれぞれが個別の正規化された文字列値を持つすべての要素のセットを選択します。

  4. 一意の正規化された文字列値で選択されたそのようなものごとに、同じ正規化された文字列値を持つautori/autore2番目のようなものがあることもテストします。autori/autoreこのような要素をすべて選択しますautori/autore。このノードセットは、まさにこの問題を選択するために必要なものです。


II。XSLT 2.0ソリューション

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text"/>

 <xsl:variable name="vSeq" select="//autori/autore/normalize-space()"/>
 <xsl:template match="/">
     <xsl:value-of select="$vSeq[index-of($vSeq,.)[2]]" separator="&#xA;"/>
 </xsl:template>
</xsl:stylesheet>

この変換が同じXMLドキュメント(上記)に適用されると、必要な正しい結果が生成されます。

Antonio Rossi
Luca Bianchi

説明

ここでは、この回答を使用し、それに応じて定義します$vSeq


III。単一のXPath3.0(およびXQuery 3.0)式-ソリューション

let $vSeq := //autori/autore/normalize-space()
 return
    $vSeq[index-of($vSeq,.)[2]]
于 2012-07-14T16:05:00.280 に答える
2

当時投稿された最初の正解を得たDevNullにおめでとうございます。彼の投稿の時点では、OPがXSLT1.0ソリューションを望んでいることは知られていませんでした。以下に1つ提供します。

XSLT 1.0で個別の値を取得するには、効率的な方法で、Muenchianグループ化が必要です。XSLT1.0でそれを行う方法は次のとおりです...

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" />

<xsl:key name="kAuthors" match="autori/autore" use="normalize-space()" />

<xsl:template match="/">
The set of authors on multiple reports
====================================== 
<xsl:for-each select="reports/report/autori/autore[
   generate-id()=
   generate-id( key('kAuthors',normalize-space())[1])]">
  <xsl:variable name="author" select="normalize-space()" />   
  <xsl:for-each select="key('kAuthors',$author)[2]">
   <xsl:value-of select="concat($author,'&#x0A;')" /> 
  </xsl:for-each>
 </xsl:for-each>  
</xsl:template>

</xsl:stylesheet>

上記のスタイルシートをOPのサンプルデータに適用すると、このテキストドキュメントが生成されます...

The set of authors on multiple reports
====================================== 
Antonio Rossi
Luca Bianchi

説明

各レポートには、著者が2回表示されます。一度autoriの下で、そして再びversioneの下で。各レポートを二重にカウントする必要がないため、キーautori/autoreの一致パターンを作成します。キー値は、文字列としての作成者の名前です。したがって、キーグループの作成者。

標準のMuenchianグループ化を使用して、作成者を反復処理します。これは、それぞれの外側です。今、私たちは「繰り返し犯人」に興味を持っています。これは、[2]述語を内側のループに適用することで取得できます。グループの長さが1つしかないため、最大1つのレポートにのみ表示される作成者は除外されます。

于 2012-07-14T14:17:32.970 に答える