XSL последний непустой узел - PullRequest
0 голосов
/ 14 апреля 2010

Учитывая следующий XML, мне нужно поместить содержимое тега суффикса (за исключением самого тега суффикса) непосредственно в конце последнего непустого текстового узла блока цитаты (как отмечено с комментариями в XML).

Мой текущий код в основном работает (таблица стилей ниже), но я не могу правильно ограничить содержание добавленного суффикса только последним узлом в блоке цитаты.

Когда добавляемый код ограничивался только обработкой текста (), он работал нормально, используя следующую инструкцию if:

<xsl:if test="generate-id() = generate-id(key('kQbText', generate-id($qb))[last()])">

Но это не работает с дочерними узлами, есть идеи? Это поставило меня в тупик.

XML:

<?xml version="1.0" encoding="utf-8"?>    
<paragraph>
    <para>
        <quote-block>
            <list prefix-rules="ordered">
                <item>
                    <para>
                        Lorem ipsum dolor sit amet, consectetur 
                        adipiscing elit. Fusce vel lorem purus, 
                        et scelerisque nibh:
                        <quote-block>
                            <quote-para>
                                "Suspendisse egestas fringilla purus. 
                                Aenean vitae augue vitae nibh convallis.
                            </quote-para>
                            <!-- last node of quote-block excluding suffix -->
                            <quote-para>
                                <emphasis strength="strong">Mperdiet vel ut 
                                orci. Ut sed neque id libero</emphasis>. 
                                cursus mattis. Phasellus eros leo, luctus 
                                in viverra dignissim."
                            </quote-para>
                            <suffix>(Emphasis added.)</suffix>
                        </quote-block>
                    </para>
                </item>             
                <item>
                    <!-- last node of quote-block excluding suffix -->
                    <para>convallis sit amet elit, mauris nisl arcu.</para>
                </item>
            </list>
            <suffix>(emphasis in original)</suffix>
        </quote-block>
    </para>
    <para>
        Curabitur suscipit, massa eu congue suscipit, tortor:
        <quote-block>
            <!-- last node of quote-block excluding suffix -->
            <quote-para>
                "estibulum quis suscipit purus. Proin ultricies 
                scelerisque egestas."
            </quote-para>
            <suffix>
                <note>
                    <note-para>Footnote text</note-para>
                </note>
            </suffix>
        </quote-block> 
        Nunc ac odio in turpis suscipit tristique.
    </para>
</paragraph>

стилевой:

<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:output method="xml" encoding="utf-8" indent="no"/>

    <!-- key to identify all non-empty, non-suffix text node descendants of
      a quote-block. We'll use that to pull out the "last one" later-on -->
    <xsl:key name="kQbText"
    match="*:quote-block//text()[not(normalize-space() = '' or parent::*:suffix)]"
    use="generate-id(ancestor::*:quote-block[1])"/>

    <!-- identity template to copy everything that is not otherwise handled -->
    <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
    </xsl:template>

    <!-- special handling for text nodes that are descendants of quote-blocks -->
    <xsl:template match="*:quote-block//text()[not(normalize-space() = '' or parent::*:suffix)]">
    <xsl:variable name="qb" select="ancestor::*:quote-block[1]"/>

    <!-- the text node gets copied regardless -->
    <xsl:copy-of select="."/>

    <!-- if it is the last non-empty text node, append all suffices -->
    <!--<xsl:if test="generate-id() = generate-id(key('kQbText', generate-id($qb))[last()])">-->
      <xsl:for-each select="$qb/*:suffix">
        <xsl:text> </xsl:text>
        <!-- copy contents of suffix node without suffix tags, inc child nodes -->
        <xsl:copy-of select="node()"/>
      </xsl:for-each>
    <!--</xsl:if>-->
    </xsl:template>

    <!-- empty text nodes will be removed (all others are copied) -->
    <xsl:template match="text()[normalize-space() = '']"/>

    <!-- suffix nodes will be deleted-->
    <xsl:template match="*:suffix"/>
</stylesheet>

1 Ответ

0 голосов
/ 14 апреля 2010

Предполагая XSLT 2.0, я думаю, что следующая таблица стилей делает то, что вы хотите:

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

  <xsl:output method="xml" encoding="utf-8" indent="no"/>

  <xsl:key name="kQbText"
    match="quote-block//text()[not(normalize-space() = '' or ancestor::suffix)]"
    use="generate-id(ancestor::*:quote-block[1])"/>

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

  <xsl:template match="quote-block//text()[not(normalize-space() = '' or ancestor::suffix)][. is key('kQbText', generate-id(ancestor::quote-block[1]))[last()]]">
    <xsl:copy/>
    <xsl:copy-of select="ancestor::quote-block[1]/suffix/node()"/>
  </xsl:template>

  <xsl:template match="quote-block/suffix"/>

</xsl:stylesheet>

При использовании Saxon 9.2, применительно к введенному вами входу, вывод выглядит следующим образом:

<?xml version="1.0" encoding="utf-8"?><paragraph>
    <para>
        <quote-block>
            <list prefix-rules="ordered">
                <item>
                    <para>
                        Lorem ipsum dolor sit amet, consectetur 
                        adipiscing elit. Fusce vel lorem purus, 
                        et scelerisque nibh:
                        <quote-block>
                            <quote-para>
                                "Suspendisse egestas fringilla purus. 
                                Aenean vitae augue vitae nibh convallis.
                            </quote-para>
                            <!-- last node of quote-block excluding suffix -->
                            <quote-para>
                                <emphasis strength="strong">Mperdiet vel ut 
                                orci. Ut sed neque id libero</emphasis>. 
                                cursus mattis. Phasellus eros leo, luctus 
                                in viverra dignissim."
                            (Emphasis added.)</quote-para>

                        </quote-block>
                    </para>
                </item>             
                <item>
                    <!-- last node of quote-block excluding suffix -->
                    <para>convallis sit amet elit, mauris nisl arcu.(emphasis in original)</para>
                </item>
            </list>

        </quote-block>
    </para>
    <para>
        Curabitur suscipit, massa eu congue suscipit, tortor:
        <quote-block>
            <!-- last node of quote-block excluding suffix -->
            <quote-para>
                "estibulum quis suscipit purus. Proin ultricies 
                scelerisque egestas."

                <note>
                    <note-para>Footnote text</note-para>
                </note>
            </quote-para>

        </quote-block> 
        Nunc ac odio in turpis suscipit tristique.
    </para>
</paragraph>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...