使用XSLT获取最后一组兄弟姐妹

时间:2010-12-07 15:38:24

标签: xml xslt

如果可用,我需要将<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:<sponsor/>元素适用于下一个<amendments/>列表之前的所有<sponsor/>

注3://amendment/id的值不是连续的。

注意4:<amendment/>无法将<sponsor/><sectionid/>作为前一个兄弟。

注5:<amendmenttext>仅适用于以下<amendment/>

如何使用XSLT 1.0完成此转换。

1 个答案:

答案 0 :(得分:2)

此样式表(与以前相同的答案,但只有一条规则):

<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>

注意:与上一个答案的不同之处在于需要这些规则中参数的默认空节点集表达式。