XSLT для выбора и преобразования узла (с совпадением регулярного выражения) и следующих братьев и сестер до следующего аналогичного узла

В некотором упрощении мой XML выглядит так:

<?xml version="1.0" encoding="UTF-8"?>
<dict>
    <entry>
        <form>word</form>
        <gram>noun</gram>
        <span style="bold">1.</span>
        <def>this is a definition in the first sense.</def> – <cit type="example">
            <quote>This is a <span style="bold">quote</span> for the first sense. </quote>
        </cit>
        <span style="bold">2.</span>
        <def>This is a definition for the second sense</def> – <cit type="example">
            <quote>This is a quote for the second sense.</quote>
        </cit>
    </entry>    
</dict>

Мне нужно преобразовать это с помощью XSLT 2.0 или 3.0, чтобы получить следующее:

<?xml version="1.0" encoding="UTF-8"?>
<dict>
    <entry>
        <form>word</form>
        <gram>noun</gram>
        <sense n="1">
            <def>this is a definition in the first sense.</def> – <cit type="example">
                <quote>This is a <span style="bold">quote</span> for the first sense. </quote>
            </cit>
        </sense>
        <sense n="2">
            <def>This is a definition for the second sense</def> – <cit type="example">
                <quote>This is a quote for the second sense.</quote>
            </cit>
        </sense>
    </entry>
</dict>

Может быть более двух значений, и жирный шрифт span может встречаться где угодно, поэтому для этого нам нужно конкретно указать что-то вроде tei:span[@style='bold'][matches(text(), '^\d\.')].

Мне сложно собрать это вместе в таблице стилей, которая также извлекает номер для текстового узла диапазона и использует его в качестве значения атрибута нового элемента <sense>.

Буду очень признателен за советы. X


person Tench    schedule 10.02.2017    source источник
comment
Можете ли вы расширить свой пример, включив в него случай, когда полужирный шрифт в стиле span может встречаться в другом месте, чтобы показать, как это следует обрабатывать (при условии, что вам не нужен для него элемент sense)? Спасибо!   -  person Tim C    schedule 10.02.2017
comment
Я только что сделал - полужирный шрифт в стиле span используется для выделения некоторых слов жирным шрифтом, но если они используются как ограничители смысла, они всегда содержат только число и точку.   -  person Tench    schedule 10.02.2017


Ответы (1)


Вот пример XSLT 3.0

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

    <xsl:mode on-no-match="shallow-copy"/>

    <xsl:output indent="yes"/>

    <xsl:template match="entry">
        <xsl:copy>
            <xsl:for-each-group select="node()" group-starting-with="span[@style = 'bold'][matches(., '^[0-9]+\.$')]">
                <xsl:choose>
                    <xsl:when test="self::span[@style = 'bold'][matches(., '^[0-9]+\.$')]">
                        <sense nr="{replace(., '[^0-9]+', '')}">
                            <xsl:apply-templates select="current-group() except ."/>
                        </sense>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:apply-templates select="current-group()"/>
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:for-each-group>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

производство продукции

<?xml version="1.0" encoding="UTF-8"?>
<dict>
    <entry>
        <form>word</form>
        <gram>noun</gram>
        <sense nr="1">
        <def>this is a definition in the first sense.</def> – <cit type="example">
            <quote>This is a <span style="bold">quote</span> for the first sense. </quote>
        </cit>
        </sense>
        <sense nr="2">
        <def>This is a definition for the second sense</def> – <cit type="example">
            <quote>This is a quote for the second sense.</quote>
        </cit>
    </sense>
    </entry>    
</dict>
person Martin Honnen    schedule 10.02.2017
comment
Спасибо, Мартин! Отлично. - person Tench; 11.02.2017