получить последнюю группу предыдущих братьев и сестер с XSLT - PullRequest
1 голос
/ 07 декабря 2010

Мне нужно вставить в элемент <amendment/> элементы <sectionid/>, <amendmenttext/> и <sponsor/>, если они доступны.

Вот пример:

От:

<root>
      <amendment>
            <id>1</id>
            <text>some text</text>
      </amendment>
      <sectionid>A</sectionid>
      <sponsor>jon</sponsor>
      <sponsor>peter</sponsor>
      <amendment>
            <id>8</id>
            <text>some text</text>
      </amendment>
      <sectionid>B</sectionid>
      <sponsor>matt</sponsor>
      <sponsor>ben</sponsor>
      <amendmenttext>some intro text</amendmenttext>
      <amendment>
            <id>5</id>
            <text>some text</text>
      </amendment>
      <amendment>
            <id>4</id>
            <text>some text</text>
      </amendment>
      <sponsor>max</sponsor>
      <amendment>
            <id>6</id>
            <text>some text</text>
      </amendment>
      <amendment>
            <id>7</id>
            <text>some text</text>
      </amendment>

</root>

до:

<root>
      <amendment>                
            <id>1</id>
            <text>some text</text>
      </amendment>          
      <amendment>
            <sectionid>A</sectionid>
            <sponsor>jon</sponsor>
            <sponsor>peter</sponsor>
            <id>8</id>
            <text>some text</text>
      </amendment>
      <amendment>
            <sectionid>B</sectionid>
            <sponsor>matt</sponsor>
            <sponsor>ben</sponsor>
            <amendmenttext>some intro</amendmenttext>
            <id>5</id>
            <text>some text</text>
      </amendment>
      <amendment>
            <sectionid>B</sectionid>
            <sponsor>matt</sponsor>
            <sponsor>ben</sponsor>
            <id>4</id>
            <text>some text</text>
      </amendment>
      <amendment>
            <sectionid>B</sectionid>
            <sponsor>max</sponsor>
            <id>6</id>
            <text>some text</text>
      </amendment>
      <amendment>
            <sectionid>B</sectionid>
            <sponsor>max</sponsor>
            <id>7</id>
            <text>some text</text>
      </amendment>

</root>

Примечание 1: элемент <sectionid/> применяется ко всем <amendments/> до следующего <sectionid/>

Примечание 2: *Элемент 1020 * применяется ко всем <amendments/> перед следующим списком <sponsor/>.

Примечание 3: значения //amendment/id не являются последовательными.

Примечание 4: <amendment/>не может иметь <sponsor/> или <sectionid/> в качестве предыдущего брата или сестры.

Примечание 5: <amendmenttext> относится только к следующим <amendment/>

Как это преобразование может быть выполнено с помощью XSLT 1.0.

1 Ответ

2 голосов
/ 07 декабря 2010

Эта таблица стилей (тот же ответ, что и раньше, но только одно правило):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:strip-space elements="*"/>
    <xsl:template match="node()|@*">
        <xsl:param name="pSectionId" select="/.."/>
        <xsl:param name="pSponsors" select="/.."/>
        <xsl:variable name="vSectionid" select="self::sectionid"/>
        <xsl:variable name="vSponsor" select="self::sponsor"/>
        <xsl:variable name="vAmendment" select="self::amendment"/>
        <xsl:if test="not($vSectionid|$vSponsor)">
            <xsl:copy>
                <xsl:apply-templates select="@*"/>
                <xsl:copy-of select="$pSectionId[$vAmendment]"/>
                <xsl:copy-of select="$pSponsors[$vAmendment]"/>
                <xsl:apply-templates select="node()[1]"/>
            </xsl:copy>
        </xsl:if>
        <xsl:apply-templates select="following-sibling::node()[1]">
            <xsl:with-param name="pSectionId"
                           select="$pSectionId[not($vSectionid)]|$vSectionid"/>
            <xsl:with-param name="pSponsors"
                            select="$pSponsors[not($vSponsor) or
                                               current()
                                                  /preceding-sibling::node()[1]
                                                     /self::sponsor] |
                                    $vSponsor"/>
        </xsl:apply-templates>
    </xsl:template>
</xsl:stylesheet>

Выход:

<root>
    <amendment>
        <id>1</id>
        <text>some text</text>
    </amendment>
    <amendment>
        <sectionid>A</sectionid>
        <sponsor>jon</sponsor>
        <sponsor>peter</sponsor>
        <id>8</id>
        <text>some text</text>
    </amendment>
    <amendment>
        <sectionid>B</sectionid>
        <sponsor>matt</sponsor>
        <sponsor>ben</sponsor>
        <id>5</id>
        <text>some text</text>
    </amendment>
    <amendment>
        <sectionid>B</sectionid>
        <sponsor>matt</sponsor>
        <sponsor>ben</sponsor>
        <id>4</id>
        <text>some text</text>
    </amendment>
    <amendment>
        <sectionid>B</sectionid>
        <sponsor>max</sponsor>
        <id>6</id>
        <text>some text</text>
    </amendment>
    <amendment>
        <sectionid>B</sectionid>
        <sponsor>max</sponsor>
        <id>7</id>
        <text>some text</text>
    </amendment>
</root>

Примечание : Отличие от предыдущего ответа - выражение набора пустых узлов по умолчанию для параметров в тех правилах, которые необходимы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...