XSL:兄弟轴的问题。位置()是答案吗?

时间:2013-09-21 12:53:16

标签: xml xslt xslt-2.0

我的xml近似于:

<?xml version="1.0" encoding="UTF-8"?>
<book>
    <num>Book 1.</num>
    <head> Title</head>
    <chapter>
        <num>1.</num>
        <head> The Begining</head>
        <p>content</p>
    </chapter>
    <num>12. </num><p>we want that number untouched</p>
    <chapter>
        <num>2.</num>
        <head> The Middle</head>
        <p>content</p>
    </chapter>
    <head>Heads Occur</head><p>we want that head untouched</p>
</book>

<num>紧跟<head>之后我希望将两者合并在一起。我使用这个xsl,取得了一些成功,但并非在所有用例中都使用。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">

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

    <xsl:template match="num[following-sibling::head]">
        <mergedhead>
            <xsl:apply-templates select="node()|@*"/>
            <xsl:value-of select="following-sibling::head"/>
        </mergedhead>    
    </xsl:template>
    <!-- keep the old head from showing up in the new output-->
    <xsl:template match="head[preceding-sibling::num]"/>

</xsl:stylesheet>

following::siblingpreceding::sibling有效,但并非在所有用例中都有效。有时他们会将<num><head>拉入彼此不相邻的位置。输出我有缺陷的XSL:

<?xml version="1.0" encoding="UTF-8"?>
<book>
    <mergedhead>Book 1. Title</mergedhead>
    <chapter>
        <mergedhead>1. The Begining</mergedhead>
        <p>content</p>
    </chapter>
    <mergedhead>12. Heads Occur</mergedhead><p>we want that number untouched</p>
    <chapter>
        <mergedhead>2. The Middle</mergedhead>
        <p>content</p>
    </chapter>
    <p>we want that head untouched</p>
</book>

你可以看到它合并了#12,我希望不受影响,并且'head occurrence',我也想要不受影响。我知道这是因为他们是兄弟姐妹,即使中间还有其他节点。我想我想要的答案是position()。但我没有成功。

作为参考,所需的输出如下:

<?xml version="1.0" encoding="UTF-8"?>
<book>
    <mergedhead>Book 1. Title</mergedhead>
    <chapter>
        <mergedhead>1. The Begining</mergedhead>
        <p>content</p>
    </chapter>
    <num>12. </num><p>we want that number untouched</p>
    <chapter>
        <mergedhead>2. The Middle</mergedhead>
        <p>content</p>
    </chapter>
    <head>Heads Occur</head><p>we want that head untouched</p>
</book>

1 个答案:

答案 0 :(得分:2)

如果满足您的要求,请尝试使用xslt。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">

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

    <!-- Take all following sibling elements (i.e. following-sibling:*) regardless their names, from them take first one (i.e. [1]) and test it if it is head (i.e. [self::head]-->
    <xsl:template match="num[following-sibling::*[1][self::head]]">
        <mergedhead>
            <xsl:apply-templates select="node()|@*"/>
            <!-- Take the first following sibling -->
            <xsl:value-of select="following-sibling::head[1]"/>
        </mergedhead>    
    </xsl:template>
    <!-- similar to num template -->
    <xsl:template match="head[preceding-sibling::*[1][self::num]]"/>

</xsl:stylesheet>