jeudi 18 juin 2015

xslt condition output one by one

hope that someone has a suggestion about this:

I need to have in each 'a', all the 'b' that have @n equal or bigger than the @n of the 'a' in which they are.

I am using xslt 2.0 and Saxon-HE 9.6.0.5


XML source:

<blabla>
    <a n="2"></a>
    <a n="6"></a>
    <b n="6"></b>
    <b n="1"></b>
    <b n="4"></b>
</blabla>


XSLT:

<xsl:stylesheet xmlns:xsl="http://ift.tt/tCZ8VR"
xmlns:xs="http://ift.tt/tphNwY"
exclude-result-prefixes="xs" version="2.0">   

<xsl:template match="blabla">
    <all>
        <xsl:for-each select="//a">
            <a>
                <xsl:attribute name="n" select="./@n"/>
                <xsl:for-each select="//b">
                    <xsl:if test="./@n[. >= //a/@n]">
                        <b>
                            <xsl:attribute name="n" select="./@n"/>
                        </b>
                    </xsl:if>
                </xsl:for-each>
            </a>
        </xsl:for-each>
    </all>
</xsl:template>


What I would like to have is:

<all>
    <a n="2">
        <b n="6"/>
        <b n="4"/>
    </a>
    <a n="6">
        <b n="6"/>
    </a>
</all>


What I have instead is:

<all>
    <a n="2">
        <b n="6"/>
        <b n="4"/>
    </a>
    <a n="6">
        <b n="6"/>
        <b n="4"/>
    </a>
</all>

I am not sure if the whole approach is wrong or if I have to adjust something.

Just for completeness, this is the function with which I was trying to do the same thing. The output is NOTHING when I create elements inside the function:

<xsl:stylesheet version="2.0" xmlns:xsl="http://ift.tt/tCZ8VR"
xmlns:foo="http://whatever">

<xsl:function name="foo:test">
    <xsl:param name="a"/>
    <xsl:param name="b"/>
    <xsl:for-each select="$a">
        <a>
            <xsl:attribute name="n">
                <xsl:value-of select="$a"/>
            </xsl:attribute>
            <xsl:if test="$b >= $a">
                <b>
                    <xsl:attribute name="n">
                        <xsl:value-of select="$b"/>
                    </xsl:attribute>
                </b>
            </xsl:if>
        </a>
    </xsl:for-each>
</xsl:function>

<xsl:template match="/">
    test 1: <xsl:value-of select="foo:test(//a/@n, //b/@n)"/>
    test 2: <xsl:value-of select="foo:test(7, 6)"/>
    test 3: <xsl:value-of select="foo:test(3, 6)"/>
</xsl:template>


The same function, without creating elements, works fine with numbers, but not if I put as parameters the xpath expression that match the source document (it outputs everything).

<xsl:stylesheet version="2.0" xmlns:xsl="http://ift.tt/tCZ8VR"
xmlns:foo="http://whatever">

<xsl:function name="foo:foo:test">
    <xsl:param name="a"/>
    <xsl:param name="b"/>
        <xsl:if test="$b >= $a">
        a: <xsl:value-of select="$a"/>
        b: <xsl:value-of select="$b"/>
        </xsl:if>   
</xsl:function>

<xsl:template match="/">
    test 1: <xsl:value-of select="foo:test(//a/@n, //b/@n)"/>
    test 2: <xsl:value-of select="foo:test(7, 6)"/>
    test 3: <xsl:value-of select="foo:test(3, 6)"/>
</xsl:template>

</xsl:stylesheet>

Output:

    test 1: 
        a: 2 6
        b: 6 1 4
    test 2: 
    test 3: 
        a: 3
        b: 6

I don't need to do it with a function; if you have suggestions for doing it without a function, it is fine. Thank you!

Aucun commentaire:

Enregistrer un commentaire