XSLT:计算两个特定节点之间的节点

时间:2017-09-05 19:18:47

标签: xml xslt

这是xml:

<?xml version="1.0" encoding="UTF-8"?>
<file>
    <text>
        <p>
            <sentence>I bought <fruit>kiwi</fruit> at the grocery store.</sentence>
            <sentence>I also bought <fruit>bananas</fruit> at the store.</sentence>
            <sentence base="basket">Then, I bought a basket at another store.</sentence>
            <sentence>You bought <fruit>peaches</fruit> at the grocery store.</sentence>
            <sentence>You also bought <fruit>apples</fruit> at the store.</sentence>
            <sentence>he bought <fruit>pears</fruit> at the grocery store.</sentence>
            <sentence base="basket">Then, You bought a <fruit>oranges</fruit> and a basket at another store.</sentence>
            <sentence>He also bought <fruit>lemons</fruit> at the store.</sentence>
        </p>
    </text>
</file>

以下是需要修改的xslt:

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

</xsl:template>
    <xsl:template match="/">
    <html>
        <body>
            <xsl:apply-templates select="file/text/p/sentence[fruit]”/>
        </body>
        </html>
        </xsl:template>

    <xsl:template match="sentence[fruit]”>
        <p>
            <xsl:apply-templates/>
        </p>
    </xsl:template>

</xsl:stylesheet>

我需要计算<fruit>与之前和<sentence base="basket">之间的句子数量。例如,<fruit>苹果</fruit><sentence>( - 2)之后是两个<sentence base=“basket”>,在另一个<sentence>(+2)之前是两个<sentence base=“basket”><fruit>橙子</fruit>位于<sentence base=“basket”>( - 0,+ 0)内。

请帮忙。这是我需要的输出:

我在杂货店买了奇异果。(没有,+ 2)

我还在商店买了香蕉。(无,+ 1)

你在杂货店买了桃子。 (-1,+ 3)

你还在商店买了苹果。 (-2,+ 2)

他在杂货店买了梨。 (-3,+ 1)

然后,你在另一家商店买了一个橘子和一个篮子。 (0,0)

他还在商店买了柠檬。 (-1,无)

1 个答案:

答案 0 :(得分:1)

您可以使用:

<?xml version="1.0" ?>

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

    <xsl:template match="/">
        <html>
            <body>
                <xsl:apply-templates select="file/text/p/sentence[fruit]"/>
            </body>
        </html>
    </xsl:template>

    <xsl:template match="sentence[fruit]">
        <p>
            <xsl:apply-templates/>
            <xsl:text>(</xsl:text>
            <xsl:choose>
                <xsl:when test="@base='basket'">0</xsl:when>
                <xsl:when test="not(preceding-sibling::sentence[@base='basket'])">none</xsl:when>
                <xsl:when test="preceding-sibling::sentence[@base='basket']">
                    <xsl:variable name="id" select="generate-id(preceding-sibling::sentence[@base='basket'][1])"/>
                    <xsl:value-of select="concat('-', count(preceding-sibling::sentence[not(@base='basket')][generate-id(preceding-sibling::sentence[@base='basket'][1]) = $id]) + 1)"/>
                </xsl:when>
            </xsl:choose>
            <xsl:text>,</xsl:text>
            <xsl:choose>
                <xsl:when test="@base='basket'">0</xsl:when>
                <xsl:when test="not(following-sibling::sentence[@base='basket'])">none</xsl:when>
                <xsl:when test="following-sibling::sentence[@base='basket']">
                    <xsl:variable name="id" select="generate-id(following::sentence[@base='basket'][1])"/>
                    <xsl:value-of select="concat('+', count(following-sibling::sentence[not(@base='basket')][generate-id(following-sibling::sentence[@base='basket'][1]) = $id]) + 1)"/>
                </xsl:when>
            </xsl:choose>
            <xsl:text>)</xsl:text>
        </p>
    </xsl:template>

</xsl:stylesheet>