2

次の XML ファイルがあります。

<li id="s9781452281988.n39.i34"><i>See also</i>
<a class="term-ref" id="s9781452281988.n39.i6525" href="#s9781452281988.n39.i1899">Emotion</a>;
    <a class="term-ref" id="s9781452281988.n39.i6526" href="#s9781452281988.n39.i3312">Interpersonal conflict</a></li>

そして、出力を次のようにしたい:

<item>See also
 <list rend="runon">
     <item><term>Emotion</term></item>
     <item><term>Interpersonal conflict</term></item>
 </list>
</item>

基本的に、複数の a[@class='term-ref'] がある場合、最初のインスタンスはリスト rend="runon"を開始し、後続の a[@class='term-ref'] をitem/termとして含める必要がありますリスト。

以下は私の試みでしたが、期待どおりに機能せず、2番目の項目/用語(出力されていない要素)の前にリストを閉じています:

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

<xsl:template match="li">
    <xsl:element name="item">
        <xsl:apply-templates/>
    </xsl:element>
</xsl:template>

<xsl:template match="a[@class='term-ref'][1]">
    <xsl:element name="list">
        <xsl:attribute name="rend" select="'runon'"/>
        <xsl:element name="item">
            <xsl:element name="term">
                <xsl:apply-templates/>
            </xsl:element>
        </xsl:element>
        <xsl:if test="a[@class='term-ref'][position() >1]">
            <xsl:element name="item">
                <xsl:element name="term">
                    <xsl:apply-templates/>
                </xsl:element>
            </xsl:element>
        </xsl:if>
    </xsl:element>
</xsl:template>

<xsl:template match="li//text()">
    <xsl:value-of select="translate(., '.,;', '')"/>
</xsl:template>

</xsl:stylesheet>

ソース XML では、上記のスタイルシートは次の出力を生成します。

<item>See also
<list rend="runon">
    <item><term>Emotion</term></item>
</list>
    Interpersonal conflict</item>

これは正しくありません。

私は何を間違っていますか?

4

3 に答える 3

1

この短い変換 (ほぼ完全に「プッシュ スタイル」、条件付き命令、またはxsl:elementのような不要な関数呼び出しはありません):translate()replace()

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

 <xsl:template match="li">
  <item><xsl:apply-templates/></item>
 </xsl:template>

 <xsl:template match="a[@class='term-ref'][1]">
     <list rend="runon">
         <xsl:apply-templates mode="group"
              select="../a[@class='term-ref']"/>
     </list>
 </xsl:template>

 <xsl:template match="a[@class='term-ref']" mode="group">
    <item><term><xsl:apply-templates/></term></item>
 </xsl:template>
 <xsl:template match="a[@class='term-ref']|li/text()" priority="-1"/>
</xsl:stylesheet>

提供された XML ドキュメントに適用された場合 -- これ整形式です:

<li id="s9781452281988.n39.i34"><i>See also</i>
  <a class="term-ref" id="s9781452281988.n39.i6525"
     href="#s9781452281988.n39.i1899">Emotion</a>;
  <a class="term-ref" id="s9781452281988.n39.i6526"
     href="#s9781452281988.n39.i3312">Interpersonal conflict.</a>.
</li>

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

<item>See also<list rend="runon">
      <item>
         <term>Emotion</term>
      </item>
      <item>
         <term>Interpersonal conflict.</term>
      </item>
   </list>
</item>
于 2013-03-02T03:40:41.060 に答える
0

これはうまくいくはずです...

XML 入力(整形式)

<doc>
    <li id="s9781452281988.n39.i34"><i>See also</i>
        <a class="term-ref" id="s9781452281988.n39.i6525" href="#s9781452281988.n39.i1899">Emotion</a>;
        <a class="term-ref" id="s9781452281988.n39.i6526" href="#s9781452281988.n39.i3312">Interpersonal conflict.</a>.
    </li>
</doc>

XSLT 2.0

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

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

    <xsl:template match="li">
        <item>
            <xsl:apply-templates select="i/text()"/>
            <xsl:if test="a">
                <list rend="runon">
                    <xsl:apply-templates select="a"/>                   
                </list>
            </xsl:if>
        </item>
    </xsl:template>

    <xsl:template match="a">
        <item><term><xsl:apply-templates select="node()"/></term></item>
    </xsl:template>

    <xsl:template match="li//text()">
        <xsl:value-of select="replace(.,'[.,;]','')"/>
    </xsl:template>

</xsl:stylesheet>

出力

<doc>
   <item>See also<list rend="runon">
         <item>
            <term>Emotion</term>
         </item>
         <item>
            <term>Interpersonal conflict</term>
         </item>
      </list>
   </item>
</doc>
于 2013-03-01T17:28:27.293 に答える
0

これはあなたが探していることをするはずです:

<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
 exclude-result-prefixes="xs"
version="2.0">

  <xsl:template match="li">
    <xsl:element name="item">
      <xsl:apply-templates select="node()" />
      <xsl:apply-templates select="." mode="items" />
    </xsl:element>
  </xsl:template>

  <xsl:template match="li//text()">
    <xsl:value-of select="normalize-space(translate(., '.,;', ''))"/>
  </xsl:template>
  <xsl:template match="a[@class = 'term-ref']" />

  <xsl:template match="node()" mode="items" />
  <xsl:template match="li" mode="items">
    <xsl:apply-templates mode="items" />
  </xsl:template>
  <xsl:template match="li[count(a[@class = 'term-ref']) > 1]" mode="items">
    <list rend="runon">
      <xsl:apply-templates select="a[@class = 'term-ref']" mode="items" />
    </list>
  </xsl:template>

  <xsl:template match="a[@class = 'term-ref']" mode="items">
    <item>
      <term>
        <xsl:value-of select="."/>
      </term>
    </item>
  </xsl:template>
</xsl:stylesheet>

サンプル入力で実行すると、次が生成されます。

<item>
  See also<list rend="runon">
    <item>
      <term>Emotion</term>
    </item>
    <item>
      <term>Interpersonal conflict</term>
    </item>
  </list>
</item>

1 つだけの入力ファイルで実行すると、a.term-ref次のようになります。

<item>
  See also<item>
    <term>Interpersonal conflict</term>
  </item>
</item>
于 2013-03-01T17:36:20.287 に答える