1

私は xslt 2.0 を使用しています。次のサンプル xml があります。2 つの「header-gray」ノードの間にあるすべての「header-lightgray」ノードを取得したいのですが、問題は次のとおりです。「header-lightgray」がいくつあるかわかりません。そこの。そのため、position() 関数を使用できません。およびそれぞれの xsl はブレークをサポートしていません。

<t>
<parent class="header-gray"></parent>
<parent class="header-lightgray"></parent>
<parent class="header-lightgray"></parent>
<parent class="header-lightgray"></parent>
...
<parent class="header-gray"></parent>
<parent class="header-lightgray"></parent>
<parent class="header-lightgray"></parent>
<parent class="header-lightgray"></parent>
<parent class="header-gray"></parent>
</t>

それらを調べて、すべてのノード、header-gray を div に、header-lightgray を span に置き換えたいと思います。期待される出力は次のとおりです。

<div class="header-gray">
<span class="header-lightgray"/>
<span class="header-lightgray"/>
<span class="header-lightgray"/>
...
</div>
<div class="header-gray">
<span class="header-lightgray"/>
<span class="header-lightgray"/>
<span class="header-lightgray"/>
</div>

では、どうやってそれを行うのですか?

どんな助けでも大歓迎です。

Jan Vlcinskyの答えに従って共有したい解決策:

<xsl:for-each select="/t/parent[@class='header-gray']">
  <xsl:variable name="ns1" select="current()/following-sibling::parent"/>
  <xsl:variable name="ns2" select="current()/following-sibling::parent[@class='header-gray'][1]/preceding-sibling::parent"/>
  <div class="header-gray">
  <xsl:for-each select="$ns1[count(.| $ns2)=count($ns2)]">
     <span class="header-lightgray"/>      
  </xsl:for-each>
  </div>
</xsl:for-each>

上記のコードは検証していませんが、実際のコードでは同じロジックです。私が使用しているlxml 2.3がxslt 2をサポートしていないことがわかったので、xslt 2.0の方法は使用しませんでした。

4

3 に答える 3

0

この変換:

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

 <xsl:template match="/*">
  <t>
   <xsl:for-each-group select="*"
        group-starting-with="parent[@class='header-gray']">
     <div class="header-gray">
       <xsl:apply-templates select="current-group()[position() ne 1]"/>
     </div>
   </xsl:for-each-group>
  </t>
 </xsl:template>

 <xsl:template match="parent">
   <span class="{@class}"/>
 </xsl:template>
</xsl:stylesheet>

次の XML ドキュメント(整形式の XML ドキュメントになるように単一のトップ要素にラップされた、提供されたフラグメント) に適用された場合:

<t>
    <parent class="header-gray"></parent>
    <parent class="header-lightgray"></parent>
    <parent class="header-lightgray"></parent>
    <parent class="header-lightgray"></parent>
    <parent class="header-gray"></parent>
    <parent class="header-lightgray"></parent>
    <parent class="header-lightgray"></parent>
    <parent class="header-lightgray"></parent>
    <parent class="header-gray"></parent>
</t>

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

<t>
   <div class="header-gray">
      <span class="header-lightgray"/>
      <span class="header-lightgray"/>
      <span class="header-lightgray"/>
   </div>
   <div class="header-gray">
      <span class="header-lightgray"/>
      <span class="header-lightgray"/>
      <span class="header-lightgray"/>
   </div>
   <div class="header-gray"/>
</t>
于 2013-05-15T04:12:44.647 に答える
-1

これを行う1つの方法を次に示します。

この XSLT 2.0 ソリューションの場合:

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

   <xsl:template match="/*">
      <t>
         <xsl:apply-templates
           select="parent[@class = 'header-gray'][following-sibling::*]"/>
      </t>
   </xsl:template>

   <xsl:template match="*[@class = 'header-gray']">
      <div class="{@class}">
         <xsl:apply-templates
           select="
             following-sibling::*[@class = 'header-lightgray'] 
               intersect
             following-sibling::*[@class = 'header-gray'][1]/
                 preceding-sibling::*[@class = 'header-lightgray']"/>
      </div>
   </xsl:template>

   <xsl:template match="*[@class = 'header-lightgray']">
      <span class="{@class}"/>
   </xsl:template>

</xsl:stylesheet>

...提供された XML に適用されます (ドキュメントを整形式にするためにトップレベルの要素にラップされます):

<t>
  <parent class="header-gray"/>
  <parent class="header-lightgray"/>
  <parent class="header-lightgray"/>
  <parent class="header-lightgray"/>
  <parent class="header-gray"/>
  <parent class="header-lightgray"/>
  <parent class="header-lightgray"/>
  <parent class="header-lightgray"/>
  <parent class="header-gray"/>
</t>

...目的の結果が生成されます。

<t>
  <div class="header-gray">
    <span class="header-lightgray" />
    <span class="header-lightgray" />
    <span class="header-lightgray" />
  </div>
  <div class="header-gray">
    <span class="header-lightgray" />
    <span class="header-lightgray" />
    <span class="header-lightgray" />
  </div>
</t>

このソリューションは、XPath 2.0 の交差操作を利用します。

于 2013-05-14T14:36:48.993 に答える