1
<Root>
  <Envelope>
    <Header>
      <ineed>apple</ineed>
    </Header>
    <success></success>
  </Envelope>
  <Envelope>
    <Header>
      <ineed>apple</ineed>
    </Header>
    <success></success>
  </Envelope>


  <Envelope>
    <Header>
      <ineed>apple</ineed>
    </Header>
    <criticalerror></criticalerror>
  </Envelope>
  <Envelope>
    <Header>
      <ineed>apple</ineed>
    </Header>
    <success></success>
  </Envelope>


  <Envelope>
    <Header>
      <ineed>apple</ineed>
    </Header>
    <criticalerror></criticalerror>
  </Envelope>
  <Envelope>
    <Header>
      <ineed>apple</ineed>
    </Header>
    <criticalerror></criticalerror>
  </Envelope>


  <Envelope>
    <Header>
      <ineed>apple</ineed>
    </Header>
    <milderror></milderror>
  </Envelope>
  <Envelope>
    <Header>
      <ineed>apple</ineed>
    </Header>
    <success></success>
  </Envelope>
</Root>

やあ、

これを xslt で動作させる方法がわかりません。xml ファイルには常に偶数回出現する「エンベロープ」要素があります。その理由は、xml がペア (1 番目と 2 番目、3 番目と 4 番目など) に基づいて成功、エラー、または警告を示すためです。最優先事項は「criticalerror」要素です。つまり、この要素がペアに存在する場合、ペアはエラーと見なされ、要素が 2 回発生することもあります。

次の優先順位は、警告を表す「milderror」要素です。3番目の優先順位は「成功」要素です。したがって、両方がペアで「成功」を含む場合にのみ、成功と見なされます。

上記の場合、最初のペアは成功、2 番目はエラー、3 番目はエラー、4 番目は警告です。成功と警告の 2 つのエラーがあります。これにより、以下のような xml が生成されます。繰り返しますが、エラーの優先度が高く (xml で最初に発生)、次に警告が表示されます

<Root>
  <error></error>
  <error></error>
  <warning></warning>
  <success></success>
</Root>

上記の xml を使用したアクションごとに、ペアになったシナリオ (成功、エラー、警告) ごとに、アクションごとに 3 つ (つまり、私の設計はそうです) があり、これはデータパワーのアクションです。

各アクションで成功するには、「apple」である成功ペアに対応する「ineed」要素を上位 xml から取得する必要があります。これは、上位 xml のペア内のいずれかまたは両方で発生する可能性があります。ペアでも同じですが、どちらか一方または両方で発生する可能性があります。

私が持っているのは、成功のためのコンテキスト loopcount 変数 (この場合は 1) だけです。これは、すべての成功シナリオを反復します。

同様に、エラー シナリオ (この場合は 2 回ループ) の場合、対応する "ineed" 要素を最上位の xml から取得する必要があります。ループカウント変数 1、次回ループカウント変数は 2

警告シナリオについても同じです。

4

2 に答える 2

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:template match="/*">
     <Root>
      <xsl:apply-templates select="Envelope[position() mod 2 = 1]">
       <xsl:sort select=
         "not((.|following-sibling::Envelope[1])/criticalerror)"/>
       <xsl:sort select=
         "not((.|following-sibling::Envelope[1])/milderror)"/>
      </xsl:apply-templates>
     </Root>
 </xsl:template>

 <xsl:template match=
  "Envelope
    [position() mod 2 = 1
   and
     success
   and
     following-sibling::Envelope[1]/success
    ]">

  <success>
   <xsl:call-template name="getTitle"/>
  </success>
 </xsl:template>

 <xsl:template match=
  "Envelope
    [position() mod 2 = 1
   and
     (.|following-sibling::Envelope[1])/criticalerror
    ]">

  <error>
   <xsl:call-template name="getTitle"/>
  </error>
 </xsl:template>

 <xsl:template match=
  "Envelope
    [position() mod 2 = 1
   and
     (.|following-sibling::Envelope[1])/milderror
   and
     not((.|following-sibling::Envelope[1])/criticalerror)
    ]">

  <warning>
   <xsl:call-template name="getTitle"/>
  </warning>
 </xsl:template>

 <xsl:template name="getTitle">
  <xsl:value-of select=
    "(.|following-sibling::Envelope[1])
         /Header/ineed[normalize-space()]
                                       [1]
    "/>
 </xsl:template>
 <xsl:template match="text()"/>
</xsl:stylesheet>

この変換が提供された XML ドキュメントに適用された場合:

<Root>
    <Envelope>
        <Header>
            <ineed>apple</ineed>
        </Header>
        <success></success>
    </Envelope>
    <Envelope>
        <Header>
            <ineed>apple</ineed>
        </Header>
        <success></success>
    </Envelope>
    <Envelope>
        <Header>
            <ineed>apple</ineed>
        </Header>
        <criticalerror></criticalerror>
    </Envelope>
    <Envelope>
        <Header>
            <ineed>apple</ineed>
        </Header>
        <success></success>
    </Envelope>
    <Envelope>
        <Header>
            <ineed>apple</ineed>
        </Header>
        <criticalerror></criticalerror>
    </Envelope>
    <Envelope>
        <Header>
            <ineed>apple</ineed>
        </Header>
        <criticalerror></criticalerror>
    </Envelope>
    <Envelope>
        <Header>
            <ineed>apple</ineed>
        </Header>
        <milderror></milderror>
    </Envelope>
    <Envelope>
        <Header>
            <ineed>apple</ineed>
        </Header>
        <success></success>
    </Envelope>
</Root>

必要な正しい結果が生成されます。

<Root>
   <error>apple</error>
   <error>apple</error>
   <warning>apple</warning>
   <success>apple</success>
</Root>

説明:

  1. いいえ<xsl:for-each>、のみ使用され<xsl:apply-templates>ます。

  2. テンプレートは、要素Envelopeの各ペアの最初にのみ明示的に適用されます。Envelope

  3. select( の属性で指定された node-list 内の) 要素を処理した結果が出力される順序は、最初にエラー、次に警告、それ以外 (成功)xsl:apply-templatesの 2 つの指示で指定されます。xsl:sort

  4. false()ブール値がソートされるとき、が先行するという事実を使用しtrue()ます。

  5. 指定されたテンプレートは、それぞれの要素のペアに含まれるgetTitle最初の空でない要素の必要な文字列値を出力するために呼び出されます。ineedEnvelope

于 2012-01-02T15:59:45.687 に答える
0

なぜfor-eachを使用しているのですか?私の知る限り、ループカウンターは必要ありません。次のように、各ペアの最初の要素を選択します(このデザインは好きではありませんが、手放しましょう)。

次に、それらの要素のテンプレートを作成します。そのテンプレート内で、XPath式「following-sibling ::Envelope[1]」を使用してペアの2番目の要素を取得できます。

奇数の要素を並べ替える必要がある場合は、次のようにすることができます。

等々。

于 2012-01-02T15:50:41.423 に答える