0

私のXMLコードとXSLTコードの説明:要素から文字列「2」を移動しようとしています

(tr[@type='detail'] and td[@column='1'])

カテゴリーヘッダーへ

(tr [@type='categoryhead' and level='2'])

これに関するヘルプは大歓迎です

<!--=============My XML=============-->
<tbody xmlns="http://mynamespace.com">
  <tr layoutcode="" type="categoryhead" level="1" categorykey="2789" hierarchykey="4921">
    <td colname="1">Bonds</td>
  </tr>
  <tr layoutcode="" type="categoryhead" level="2" categorykey="3255" hierarchykey="4922">
    <td colname="1">Beverages</td>
  </tr>
  <tr layoutcode="" type="detail" level="3" securitymasterkey="41164">
    <td colname="1">Security_1(1,2)</td>
    <td colname="2">500</td>`enter code here`
    <td colname="3">330</td>
  </tr>
  <tr layoutcode="" type="detail" level="3" securitymasterkey="41167">
    <td colname="1">Security_4(1,2,3,4)</td>
    <td colname="2">10</td>
    <td colname="3">265</td>
  </tr>
  <tr layoutcode="" type="categorytotal" level="2" categorykey="3255" hierarchykey="4922">
    <td colname="1">Beverages</td>
    <td colname="2">530</td>
    <td colname="3">1,045</td>
  </tr>
  <tr layoutcode="" type="categorytotal" level="1" categorykey="2789" hierarchykey="4921">
    <td colname="1">TOTAL Bonds</td>
    <td colname="2">530</td>
    <td colname="3">1,045</td>
  </tr>

  <tr layoutcode="" type="categoryhead" level="1" categorykey="2936" hierarchykey="4921">
    <td colname="1">Options</td>
  </tr>
  <tr layoutcode="" type="categoryhead" level="2" categorykey="3248" hierarchykey="4922">
    <td colname="1">Agriculture</td>
  </tr>
  <tr layoutcode="" type="detail" level="3" securitymasterkey="41168">
    <td colname="1">Security_5(@,1)</td>
    <td colname="2">10</td>
    <td colname="3">890</td>
  </tr>
  <tr layoutcode="" type="detail" level="3" securitymasterkey="41168">
    <td colname="1">Security_5(@,2)</td>
    <td colname="2">10</td>
    <td colname="3">890</td>
  </tr>
  <tr layoutcode="" type="categorytotal" level="2" categorykey="3248" hierarchykey="4922">
    <td colname="1">Agriculture</td>
    <td colname="2">10</td>
    <td colname="3">890</td>
  </tr>
</tbody>

文字列 '2' を (tr[@type='detail'] および td[@column='1']) の要素からカテゴリ ヘッダー (tr [@type='categoryhead ' および level='2'])

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:a="http://mynamespace.com" version="2.0">

  <!-- Global Variable -->
  <xsl:variable name="arg1" select="'2'"></xsl:variable>

  <!-- This identity template copies the document -->
  <xsl:template match="node() | @*">
    <xsl:copy>
      <xsl:apply-templates select="node() | @* "/>
    </xsl:copy>
  </xsl:template>


  <xsl:template match="a:tbody/a:tr[@type='categoryhead' and @level='2']/a:td">
    <xsl:for-each select="//a:tbody/a:tr[@type='detail']/a:td[@colname='1'][contains(.,$arg1)]">
      <xsl:variable name="IsFooted" select="contains(.,$arg1)"></xsl:variable>
      <xsl:value-of select="count(//a:tbody/a:tr[@type='detail']/a:td[@colname='1'][contains(.,$arg1)])"/>
      <xsl:choose>
        <xsl:when test="$IsFooted='true'">
          <xsl:value-of select="."/>
          <xsl:value-of select="concat('(',concat($arg1,')'))"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="."/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

必要な XML 出力:

<tbody xmlns="http://mynamespace.com">
  <tr layoutcode="" type="categoryhead" level="1" categorykey="2789" hierarchykey="4921">
    <td colname="1">Bonds</td>
  </tr>
  <tr layoutcode="" type="categoryhead" level="2" categorykey="3255" hierarchykey="4922">
    <td colname="1">Beverages (2)</td>
  </tr>
  <tr layoutcode="" type="detail" level="3" securitymasterkey="41164">
    <td colname="1">Security_1(1)</td>
    <td colname="2">500</td>
    <td colname="3">330</td>
  </tr>
  <tr layoutcode="" type="detail" level="3" securitymasterkey="41167">
    <td colname="1">Security_4(1,3,4)</td>
    <td colname="2">10</td>
    <td colname="3">265</td>
  </tr>
  <tr layoutcode="" type="categorytotal" level="2" categorykey="3255" hierarchykey="4922">
    <td colname="1">Beverages</td>
    <td colname="2">530</td>
    <td colname="3">1,045</td>
  </tr>
  <tr layoutcode="" type="categorytotal" level="1" categorykey="2789" hierarchykey="4921">
    <td colname="1">TOTAL Bonds</td>
    <td colname="2">530</td>
    <td colname="3">1,045</td>
  </tr>

  <tr layoutcode="" type="categoryhead" level="1" categorykey="2936" hierarchykey="4921">
    <td colname="1">Options</td>
  </tr>
  <tr layoutcode="" type="categoryhead" level="2" categorykey="3248" hierarchykey="4922">
    <td colname="1">Agriculture</td>
  </tr>
  <tr layoutcode="" type="detail" level="3" securitymasterkey="41168">
    <td colname="1">Security_5(@,1)</td>
    <td colname="2">10</td>
    <td colname="3">890</td>
  </tr>
  <tr layoutcode="" type="detail" level="3" securitymasterkey="41168">
    <td colname="1">Security_5(@,2)</td>
    <td colname="2">10</td>
    <td colname="3">890</td>
  </tr>
  <tr layoutcode="" type="categorytotal" level="2" categorykey="3248" hierarchykey="4922">
    <td colname="1">Agriculture</td>
    <td colname="2">10</td>
    <td colname="3">890</td>
  </tr>
</tbody>
4

1 に答える 1

0

出力サンプルを見ると、「(2)」が特定のテーブル セルに追加されているだけなので、ここでは用語が明確ではありません。実際には何も動いていません。

また、質問の質問のタイトルは子要素について言及していますが、XML 構造を見ると、「詳細」行は実際には「カテゴリヘッド」行の兄弟です。これがおそらく問題の原因です。「詳細」行を関連する「カテゴリヘッダー」とどのように関連付けますか。これを行う1つの方法は、キーを使用することです

<xsl:key name="row" 
         match="a:tr[@level != '1']" 
         use="generate-id(preceding-sibling::a:tr[@level=current()/@level - 1][1])" />

これにより、(レベル 1 以外の) 行が取得され、下位の @level 属性を持つ最初の先行行によってグループ化されます。

ここで、テンプレートの一致について、「td」要素を変更しているため、「tr」要素ではなく、そのような要素に一致するようにテンプレートを変更します

 <xsl:template match="a:tbody/a:tr[@type='categoryhead' and @level='2']/a:td[@colname='1']">

次に、キーを使用して「子」要素を取得できますが、すべての子要素に「2」が含まれているかどうかを考える代わりに、ロジックを逆にして、子要素に「2」が含まれていないかどうかを確認します

このXSLTを試してください

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:a="http://composition.bowne.com/2010/v4" version="1.0">

  <!-- Global Variable -->
  <xsl:variable name="arg1" select="'2'"></xsl:variable>

  <xsl:key name="row" match="a:tr[@level != '1']" use="generate-id(preceding-sibling::a:tr[@level=current()/@level - 1][1])" />

  <!-- This identity template copies the document -->
  <xsl:template match="node() | @*">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="a:tbody/a:tr[@type='categoryhead' and @level='2']/a:td[@colname='1']">
      <xsl:variable name="IsMissing" select="key('row', generate-id(..))/a:td[@colname='1'][not(contains(text(), $arg1))]" />
      <xsl:choose>
        <xsl:when test="not($IsMissing)">
          <xsl:value-of select="."/>
          <xsl:value-of select="concat('(',concat($arg1,')'))"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="."/>
        </xsl:otherwise>
      </xsl:choose>
  </xsl:template>
</xsl:stylesheet>

余談ですが、XSLT の名前空間は XML の名前空間と一致しません。これが機能するにはこれらが一致する必要がありますが、これはタイプミスだと思います。

編集:「詳細」行から「2」を削除するには、次のテンプレートを追加してみてください。「isMissing」変数は、関連する「categoryhead」を最初に見つける必要があるため、少し複雑です。また、XSLT 2.0 でのみ使用可能な「置換」を使用していることにも注意してください。

  <xsl:template match="a:tbody/a:tr[@type='detail']/a:td[@colname='1']">
    <xsl:variable name="parentLevel" select="../@level - 1" />
    <xsl:variable name="IsMissing" select="key('row', generate-id(../preceding-sibling::a:tr[@level=$parentLevel][1]))/a:td[@colname='1'][not(contains(text(), $arg1))]" />
      <xsl:choose>
        <xsl:when test="not($IsMissing)">
          <xsl:value-of select="replace(., concat(',', $arg1), '')"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="."/>
        </xsl:otherwise>
      </xsl:choose>
  </xsl:template>
于 2013-10-08T08:03:59.227 に答える