2

次のような XML ドキュメントがあります。

<Root>
    <Cover>
        <Cover_Ref Val="1"/>
        <Cover_Code Val="Food in transit"/>
        <AdditionalCover>
            <AdditionalCover_Area Val="Sussex"/>
        </AdditionalCover>
    </Cover>
    <Cover>
        <Cover_Ref Val="2"/>
        <Cover_Code Val="Frozen goods"/>
    </Cover>
    <Cover>
        <Cover_Ref Val="3"/>
        <Cover_Code Val="Business equipment"/>
        <AdditionalCover>
            <AdditionalCover_Area Val="Sussex"/>
        </AdditionalCover>
    </Cover>
    <AdditionalCoverResult>
        <CoverArea Val="Sussex"/>
        <CoverExcluded Val="N"/>
    </AdditionalCoverResult>
    <AdditionalCoverResult>
        <CoverArea Val="Sussex"/>
        <CoverExcluded Val="Y"/>
    </AdditionalCoverResult>
</Root>

私はそれを次のようなものに変換する必要があります:

<Insurances>
    <Insurance>
        <reference>1</reference>
        <CoverType>Food in transit</CoverType>
        <Region>Sussex</Region>
        <Excluded>N</Excluded>
    </Insurance>
    <Insurance>
        <reference>2</reference>
        <CoverType>Frozen goods</CoverType>
    </Insurance>
    <Insurance>
        <reference>3</reference>
        <CoverType>Business equipment</CoverType>
        <Region>Sussex</Region>
        <Excluded>Y</Excluded>
    </Insurance>
</Insurances>

AdditionalCoverResult 要素は、AdditionalCover 要素を含む Cover 要素を参照します。つまり、最初の Cover 要素のカバーは除外されず、3 番目の Cover 要素のカバーは除外されます。2 番目の cover 要素には AdditionalCover がないため、それを参照する AdditionalCoverResult 要素はありません。

私の問題は、<xsl:for-each select="//Cover">ループ内で、探しているAdditionalCoverResult要素を特定する方法を考えられないことです。for-each 内で使用position()すると、AdditionalCover を持たない Cover 要素の AdditionalCoverResult 情報が誤って出力されてしまいます。

Cover の元の順序を保持する必要があるため、AdditionalCover を使用する Cover と AdditionalCover を使用しない Cover の 2 つの別々のループを実行することはできません。

によって返されたノードセット内で、によって返され//Coverたノードセット内のコンテキストノードの位置を特定できる方法はあります//Cover[AdditionalCover]か?

//Cover[AdditionalCover]Cover 要素については、 「対応する AdditionalCoverResult 要素を識別するためにそのインデックスを使用できるようにするには、どのインデックス内にいるのか」と考える必要があると推測しています。

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:template match="/*">
  <Insurances>
   <xsl:apply-templates select="Cover"/>
  </Insurances>
 </xsl:template>

 <xsl:template match="Cover">
  <Insurance>
   <xsl:apply-templates/>
  </Insurance>
 </xsl:template>

 <xsl:template match="Cover_Ref">
  <reference><xsl:value-of select="@Val"/></reference>
 </xsl:template>

 <xsl:template match="Cover_Code">
  <CoverType><xsl:value-of select="@Val"/></CoverType>
 </xsl:template>

 <xsl:template match="AdditionalCover_Area">
  <Region><xsl:value-of select="@Val"/></Region>

  <Excluded>
    <xsl:value-of select=
    "/*/AdditionalCoverResult[CoverArea/@Val=current()/@Val]
             [position()
             =
              1 +count(current()
                       /ancestor::Cover[1]
                          /preceding-sibling::Cover
                            [AdditionalCover
                              /AdditionalCover_Area/@Val
                            =
                             current()/@Val
                            ]
                      )
              ]
               /CoverExcluded/@Val
    "/>
  </Excluded>
 </xsl:template>
</xsl:stylesheet>

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

<Root>
    <Cover>
        <Cover_Ref Val="1"/>
        <Cover_Code Val="Food in transit"/>
        <AdditionalCover>
            <AdditionalCover_Area Val="Sussex"/>
        </AdditionalCover>
    </Cover>
    <Cover>
        <Cover_Ref Val="2"/>
        <Cover_Code Val="Frozen goods"/>
    </Cover>
    <Cover>
        <Cover_Ref Val="3"/>
        <Cover_Code Val="Business equipment"/>
        <AdditionalCover>
            <AdditionalCover_Area Val="Sussex"/>
        </AdditionalCover>
    </Cover>
    <AdditionalCoverResult>
        <CoverArea Val="Sussex"/>
        <CoverExcluded Val="N"/>
    </AdditionalCoverResult>
    <AdditionalCoverResult>
        <CoverArea Val="Sussex"/>
        <CoverExcluded Val="Y"/>
    </AdditionalCoverResult>
</Root>

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

<Insurances>
   <Insurance>
      <reference>1</reference>
      <CoverType>Food in transit</CoverType>
      <Region>Sussex</Region>
      <Excluded>N</Excluded>
   </Insurance>
   <Insurance>
      <reference>2</reference>
      <CoverType>Frozen goods</CoverType>
   </Insurance>
   <Insurance>
      <reference>3</reference>
      <CoverType>Business equipment</CoverType>
      <Region>Sussex</Region>
      <Excluded>Y</Excluded>
   </Insurance>
</Insurances>
于 2012-05-26T04:39:57.260 に答える
0

関心のある現在のコンテキストの一部を変数に格納できます。たとえば、次のようになります。

<xsl:for-each select="//Cover">

  ...

  <xsl:variable name="additional" select="AdditionalCover/AdditionalCover_Area/@Val"/>
  <xsl:if select="$additional">
    <Excluded>
      <xsl:value-of select="AdditionalCoverResult[CoverArea/@Val = $additional]/CoverExcluded/@Val"/>
    </Excluded>
  </xsl:if>
</xs:for-each>
于 2012-05-25T10:11:28.693 に答える
0

質問を投稿した後、関連セクションにリンクが表示されました-同じ名前のすべてのノードに関連するコンテキストノードのインデックスを決定するためのxpath / xslt?

Dimitre Novatchevの回答は、

count(preceding::question)+1

questionドキュメント内のすべての要素に関連する現在のコンテキストノードのインデックスを見つけることができます。

私が使用count(preceding::Cover[AdditionalCover])+1した質問では、それは機能しました-私はそれを正しく理解したことを望んでいますが、それはうまくいくようです。

誰かがこれを行う他の方法があるかどうか非常に興味があるので、私はこれをすぐに正しい答えとして選択しません-私はおそらくXSLTの中間レベルであり、これはそれについてもう少し学ぶ絶好の機会です!

于 2012-05-25T10:11:54.750 に答える