-4

以下のソース XML に基づいて、NOTE#:を<emphasis>含まないテキスト ノードと要素を、対応するNOTE#:要素と共にキャプチャします。<emphasis bold="yes"></emphasis><emphasis bold="yes"></emphasis>

ソース XML:

<section>
  <para>
    <emphasis bold="yes">NOTE1:</emphasis> This is the text of the first note 1 <emphasis bold="yes">that should only be in the <emphasis italic="yes">first</emphasis> subsection occurance of note one.</emphasis>. This is the second sentence of the first note one. <emphasis italic="yes">Here is some other text</emphasis> that can appear. <emphasis bold="yes">Marvin Gaye is an excellent musician1.</emphasis> Play it for your girlfriend1 <emphasis italic="yes">now1.</emphasis>.
    <emphasis bold="yes">NOTE2:</emphasis> This is the text of  the first note two2.1 <emphasis italic="yes">The Isley Brothers are also good.2.1</emphasis>
    <emphasis bold="yes">NOTE1:</emphasis> This is the text of the second note one.1.2 <emphasis italic="yes">My girlfriend loves them1.2</emphasis>
    <emphasis bold="yes">NOTE3:</emphasis> This is the text of the first note three3.1.
    <emphasis bold="yes">NOTE1:</emphasis> This is the text of the third note one.1.3<emphasis italic="yes">She is going to make me dinner tonight1.3</emphasis>
    <emphasis bold="yes">NOTE3:</emphasis> This is the text of the second note three.3.2<emphasis italic="yes">Steak and potatos3.2</emphasis>
    <emphasis bold="yes">NOTE2:</emphasis> This is the text of the second note two.2.2<emphasis italic="yes">And then some wine2.2</emphasis>
  </para>
</section>

現在の XSLT:

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

  <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

  <xsl:template match="*|@*|text()">
    <xsl:copy>
      <xsl:apply-templates select="*|@*|text()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="section">
    <root>
      <xsl:apply-templates select="*|@*|text()"/>
    </root>
  </xsl:template>

  <xsl:template match="para/emphasis[preceding-sibling::emphasis[@bold='yes' and text()='NOTE1:']]"/>
  <xsl:template match="para/emphasis[preceding-sibling::emphasis[@bold='yes' and text()='NOTE2:']]"/>
  <xsl:template match="para/emphasis[preceding-sibling::emphasis[@bold='yes' and text()='NOTE3:']]"/>
  <xsl:template match="para/text()[preceding-sibling::emphasis[@bold='yes' and text()='NOTE1:']]"/>
  <xsl:template match="para/text()[preceding-sibling::emphasis[@bold='yes' and text()='NOTE2:']]"/>
  <xsl:template match="para/text()[preceding-sibling::emphasis[@bold='yes' and text()='NOTE3:']]"/>

  <xsl:template match="para/emphasis[@bold='yes' and text()='NOTE1:' and not(position()=last())]">
    <subsection>
      <para>
        <emphasis bold="yes">NOTE1:</emphasis>
        <xsl:copy-of
          select="following-sibling::text()[not(preceding-sibling::emphasis[@bold='yes' and text()='NOTE2:'])  and not(preceding-sibling::emphasis[@bold='yes' and text()='NOTE3:'])] |following-sibling::emphasis[not(contains(string(), 'NOTE1:'))  and  not(contains(string(), 'NOTE2:'))  and not(contains(string(), 'NOTE3:'))]"
        />
      </para>
    </subsection>
  </xsl:template>

  <xsl:template match="para/emphasis[position()=last() and position() > 1  and @bold='yes' and text()='NOTE1:']">
    <subsection>
      <para>
        <emphasis bold="yes">NOTE1:</emphasis>
        <xsl:copy-of
          select="following-sibling::text()[position() = 1]|following-sibling::emphasis[not(contains(string(), 'NOTE1:'))  and  not(contains(string(), 'NOTE2:'))  and not(contains(string(), 'NOTE3:'))]"
        />
      </para>
    </subsection>
  </xsl:template>

  <xsl:template match="para/emphasis[@bold='yes' and text()='NOTE2:' and not(position()=last())]">
    <subsection>
      <para>
        <emphasis bold="yes">NOTE2:</emphasis>
        <xsl:copy-of
          select="following-sibling::text()[not(preceding-sibling::emphasis[@bold='yes' and text()='NOTE1:'])  and not(preceding-sibling::emphasis[@bold='yes' and text()='NOTE3:'])] |following-sibling::emphasis[not(contains(string(), 'NOTE1:'))  and  not(contains(string(), 'NOTE2:'))  and not(contains(string(), 'NOTE3:'))]"
        />
      </para>
    </subsection>
  </xsl:template>

  <xsl:template match="para/emphasis[position()=last() and position() > 1 and @bold='yes' and text()='NOTE2:']">
    <note>
      <para>
        <emphasis bold="yes">NOTE2:</emphasis>
        <xsl:copy-of
          select="following-sibling::text()[position() = 1]|following-sibling::emphasis[not(contains(string(), 'NOTE1:'))  and  not(contains(string(), 'NOTE2:')) and not(contains(string(), 'NOTE3:'))  ]"
        />
      </para>
    </note>
  </xsl:template>

  <xsl:template match="para/emphasis[@bold='yes' and text()='NOTE3:' and not(position()=last())]">
    <note>
      <para>
        <emphasis bold="yes">NOTE3:</emphasis>
        <xsl:copy-of
          select="following-sibling::text()[not(preceding-sibling::emphasis[@bold='yes' and text()='NOTE2:'])  and not(preceding-sibling::emphasis[@bold='yes' and text()='NOTE1:'])] | following-sibling::emphasis[not(contains(string(), 'NOTE1:'))  and  not(contains(string(), 'NOTE2:'))  and not(contains(string(), 'NOTE3:'))]"
        />
      </para>
    </note>
  </xsl:template>

  <xsl:template match="para/emphasis[position()=last() and position() > 1 and @bold='yes' and text()='NOTE3:']">
    <note>
      <para>
        <emphasis bold="yes">NOTE3:</emphasis>
        <xsl:copy-of select="following-sibling::text()[position() = 1]|following-sibling::emphasis[not(contains(string(), 'NOTE1:'))  and  not(contains(string(), 'NOTE2:'))  and not(contains(string(), 'NOTE3:'))  ]"/>
      </para>
    </note>
  </xsl:template>

</xsl:stylesheet>

現在の出力:

<root>
  <para>
    <subsection>
      <para>
        <emphasis bold="yes">NOTE1:</emphasis> This is the text of the first note 1 <emphasis bold="yes">that should only be in the <emphasis italic="yes">first</emphasis> subsection occurance of note one.</emphasis>. This is the second sentence of the first note one. <emphasis italic="yes">Here is some other text</emphasis> that can appear. <emphasis bold="yes">Marvin Gaye is an excellent musician1.</emphasis> Play it for your girlfriend1 <emphasis italic="yes">now1.</emphasis>.
        <emphasis italic="yes">The Isley Brothers are also good.2.1</emphasis>
        <emphasis italic="yes">My girlfriend loves them1.2</emphasis>
        <emphasis italic="yes">She is going to make me dinner tonight1.3</emphasis>
        <emphasis italic="yes">Steak and potatos3.2</emphasis>
        <emphasis italic="yes">And then some wine2.2</emphasis>
      </para>
    </subsection>
    <subsection>
      <para>
        <emphasis bold="yes">NOTE2:</emphasis>
        <emphasis italic="yes">The Isley Brothers are also good.2.1</emphasis>
        <emphasis italic="yes">My girlfriend loves them1.2</emphasis>
        <emphasis italic="yes">She is going to make me dinner tonight1.3</emphasis>
        <emphasis italic="yes">Steak and potatos3.2</emphasis>
        <emphasis italic="yes">And then some wine2.2</emphasis>
      </para>
    </subsection>
    <subsection>
      <para>
        <emphasis bold="yes">NOTE1:</emphasis>
        <emphasis italic="yes">My girlfriend loves them1.2</emphasis>
        <emphasis italic="yes">She is going to make me dinner tonight1.3</emphasis>
        <emphasis italic="yes">Steak and potatos3.2</emphasis>
        <emphasis italic="yes">And then some wine2.2</emphasis>
      </para>
    </subsection>
    <note>
      <para>
        <emphasis bold="yes">NOTE3:</emphasis>
        <emphasis italic="yes">She is going to make me dinner tonight1.3</emphasis>
        <emphasis italic="yes">Steak and potatos3.2</emphasis>
        <emphasis italic="yes">And then some wine2.2</emphasis>
      </para>
    </note>
    <subsection>
      <para>
        <emphasis bold="yes">NOTE1:</emphasis>
        <emphasis italic="yes">She is going to make me dinner tonight1.3</emphasis>
        <emphasis italic="yes">Steak and potatos3.2</emphasis>
        <emphasis italic="yes">And then some wine2.2</emphasis>
      </para>
    </subsection>
    <note>
      <para>
        <emphasis bold="yes">NOTE3:</emphasis>
        <emphasis italic="yes">Steak and potatos3.2</emphasis>
        <emphasis italic="yes">And then some wine2.2</emphasis>
      </para>
    </note>
    <subsection>
      <para>
        <emphasis bold="yes">NOTE2:</emphasis>
        <emphasis italic="yes">And then some wine2.2</emphasis>
      </para>
    </subsection>
  </para>
</root>


Desired output:

<root>
  <para>
    <subsection>
      <para>
        <emphasis bold="yes">NOTE1:</emphasis> This is the text of the first note 1 <emphasis bold="yes">that should only be in the <emphasis italic="yes">first</emphasis> subsection occurance of note one.</emphasis>. This is the second sentence of the first note one. <emphasis italic="yes">Here is some other text</emphasis> that can appear. <emphasis bold="yes">Marvin Gaye is an excellent musician1.</emphasis> Play it for your girlfriend1 <emphasis italic="yes">now1.</emphasis>.
      </para>
    </subsection>
    <subsection>
      <para>
        <emphasis bold="yes">NOTE2:</emphasis>This is the text of  the first note two2.1<emphasis italic="yes">The Isley Brothers are also good.2.1</emphasis>
      </para>
    </subsection>
    <subsection>
      <para>
        <emphasis bold="yes">NOTE1:</emphasis> This is the text of the second note one.1.2 <emphasis italic="yes">My girlfriend loves them1.2</emphasis>
      </para>
    </subsection>
    <subsection>
      <para>
        <emphasis bold="yes">NOTE3:</emphasis> This is the text of the first note three3.1.
      </para>
    </subsection>
    <subsection>
      <para>
        <emphasis bold="yes">NOTE1:</emphasis> This is the text of the third note one.1.3<emphasis italic="yes">She is going to make me dinner tonight1.3</emphasis>
      </para>
    </subsection>
    <subsection>
      <para>
        <emphasis bold="yes">NOTE3:</emphasis> This is the text of the second note three.3.2<emphasis italic="yes">Steak and potatos3.2</emphasis>
      </para>
    </subsection>
    <subsection>
      <para>
        <emphasis bold="yes">NOTE2:</emphasis> This is the text of the second note two.2.2<emphasis italic="yes">And then some wine2.2</emphasis>
      </para>
    </subsection>
  </para>
</root>
4

1 に答える 1

2

私があなたの要件を正しく理解していれば、あなたの XSLT は少し複雑すぎると思います。ノードをグループ化したいだけのように見えます。各グループの開始は、テキスト状態「NOTE」の強調ノードで表されます。

XSLT 2.0 を使用していると仮定すると (現在の XSLT は version="2.0" とマークされているため)、便利なxsl:for-each-groupコマンドを紹介します。これはまさに必要なものです。あなたの場合、関連する強調要素で始まるノードをグループ化します。

<xsl:for-each-group 
    select="node()" 
    group-starting-with="emphasis[starts-with(text(), 'NOTE')]">

この中で、 subsection要素とpara要素を出力し、グループ内の要素を反復してコピーします。

<xsl:apply-templates select="current-group()" />

強調要素自体を出力するには、 XSLT 恒等変換を使用します。

これは幸いなことにはるかに短い XSLT です。

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

   <xsl:template match="para">
      <para>
         <xsl:for-each-group select="node()" group-starting-with="emphasis[starts-with(text(), 'NOTE')]">
            <subsection>
               <para>
                  <xsl:apply-templates select="current-group()" />
               </para>
            </subsection>
         </xsl:for-each-group>
      </para>
   </xsl:template>

   <xsl:template match="@*|node()">
      <xsl:copy>
         <xsl:apply-templates select="@*|node()"/>
      </xsl:copy>
   </xsl:template>
</xsl:stylesheet>

XML に適用すると、以下が出力されます。

<section>
   <para>
      <subsection>
         <para>
            <emphasis bold="yes">NOTE1:</emphasis> This is the text of the first note 1 
            <emphasis bold="yes">that should only be in the 
               <emphasis italic="yes">first</emphasis>subsection occurance of note one. 
            </emphasis>. This is the second sentence of the first note one. 
            <emphasis italic="yes">Here is some other text</emphasis>that can appear. 
            <emphasis bold="yes">Marvin Gaye is an excellent musician1.</emphasis>Play it for your girlfriend1 
            <emphasis italic="yes">now1.</emphasis>. 
         </para>
      </subsection>
      <subsection>
         <para>
            <emphasis bold="yes">NOTE2:</emphasis>This is the text of the first note two2.1 
            <emphasis italic="yes">The Isley Brothers are also good.2.1</emphasis></para>
      </subsection>
      <subsection>
         <para>
            <emphasis bold="yes">NOTE1:</emphasis>This is the text of the second note one.1.2 
            <emphasis italic="yes">My girlfriend loves them1.2</emphasis></para>
      </subsection>
      <subsection>
         <para>
            <emphasis bold="yes">NOTE3:</emphasis>This is the text of the first note three3.1. </para>
      </subsection>
      <subsection>
         <para>
            <emphasis bold="yes">NOTE1:</emphasis>This is the text of the third note one.1.3 
            <emphasis italic="yes">She is going to make me dinner tonight1.3</emphasis></para>
      </subsection>
      <subsection>
         <para>
            <emphasis bold="yes">NOTE3:</emphasis> This is the text of the second note three.3.2 
            <emphasis italic="yes">Steak and potatos3.2</emphasis></para>
      </subsection>
      <subsection>
         <para>
            <emphasis bold="yes">NOTE2:</emphasis> This is the text of the second note two.2.2 
            <emphasis italic="yes">And then some wine2.2</emphasis></para>
      </subsection>
   </para>
</section>

XSLT 2.0 でグループ化する方法の例については、http://www.xml.com/lpt/a/1314を参照してください。

于 2013-05-10T22:35:22.590 に答える