1

xsltにはbreakステートメントがなく、問題を解決する方法がわからないことを私は知っています。

      <tag name="param" />
      <tag name="Token" />
      <tag name="Token" />
      <tag name="Token" />
      <tag name="param" />
      <tag name="Token" />
      <tag name="param" />
      <tag name="Token" />
      <tag name="Token" />
      <tag name="Token" />
      <tag name="return"/>

次のパラメータの前に、パラメータをすべてのトークンとグループ化する必要があります。どうすればいいですか?

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

param
    Token
    Token
    Token
param
    Token
param
    Token
    Token
    Token   
4

2 に答える 2

5

これを実現する別の方法は、「非パラメータ」要素を一致させ、最初に先行するパラメータ要素でグループ化するためのキーです。

<xsl:key 
  name="params" 
  match="tag[@name!='param']" 
  use="generate-id(preceding-sibling::tag[@name='param'][1])" />

次に、「param」要素を照合することから始めます

<xsl:apply-templates select="tag[@name='param']" />

そして、一致するものごとに、キーを使用してグループ内の関連するタグを選択できます

<xsl:apply-templates select="key('params', generate-id())" />

次のXSLTを試してください

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="text" />
   <xsl:key name="params" match="tag[@name!='param']" use="generate-id(preceding-sibling::tag[@name='param'][1])" />

   <xsl:template match="/*">
      <xsl:apply-templates select="tag[@name='param']" />
   </xsl:template>

   <xsl:template match="tag[@name='param']">
      <xsl:text>param&#10;</xsl:text> 
      <xsl:apply-templates select="key('params', generate-id())" />
   </xsl:template>

   <xsl:template match="tag">
      <xsl:value-of select="concat(' - ', @name, '&#10;')" />
   </xsl:template>
</xsl:stylesheet>

サンプルXMLに適用すると(ルート要素を想定)、次のように出力されます。

param
 - Token
 - Token
 - Token
param
 - Token
param
 - Token
 - Token
 - Token
 - return

「return」要素が必要ない場合は、それに一致する別のテンプレートを追加して、無視することができます。

于 2012-10-01T22:45:19.167 に答える
3

XSLT 2.0では、これを使用すると簡単ですfor-each-groupが、XSLT1.0ではそれほど単純ではありません。グループを区別する1つの方法は、次の兄弟paramタグを数えることです。

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

  <xsl:output method="text"/>

  <xsl:template match="/">
    <xsl:apply-templates select="*/tag[@name = 'param']" />
  </xsl:template>

  <xsl:template match="tag[@name = 'param']">
    <xsl:text>param&#x0a;</xsl:text>
    <xsl:apply-templates select="following-sibling::tag[@name = 'Token']
       [count(following-sibling::tag[@name='param'])
         = count(current()/following-sibling::tag[@name='param'])]" />
  </xsl:template>

  <xsl:template match="tag[@name = 'Token']">
    <xsl:text>&#x09;Token&#x0a;</xsl:text>
  </xsl:template>
</xsl:stylesheet>

ここでは、最初に使用Tokenしたのと同じ数の次のparamタグを持つタグparam、つまり次のパラメーターの前に発生するタグを選択しています。これはかなり非効率的であり、タグの数がO(N 2 )であることに注意してください。より効率的なアプローチは、末尾再帰テンプレートを使用して、各トークンを「先読み」して、次のパラメーターの前の最後のトークンであるかどうかを確認することです。

<xsl:template match="tag[@name = 'param']">
  <xsl:text>param&#x0a;</xsl:text>
  <xsl:apply-templates select="following-sibling::tag[1][@name = 'Token']" />
</xsl:template>

<xsl:template match="tag[@name = 'Token']">
  <xsl:text>&#x09;Token&#x0a;</xsl:text>
  <xsl:apply-templates select="following-sibling::tag[1][@name = 'Token']" />
</xsl:template>

ここで、テンプレートは最初のparam後続のトークンにテンプレートを適用し、トークンテンプレートは、最初の後続の兄弟が別のトークンであるかどうかをチェックし、そうである場合は、テンプレートを再帰的に適用します。

于 2012-10-01T22:00:07.297 に答える