سؤال

I need an advice if the way I am trying to implement what I am trying to implement :) is wrong or not. I have an input XML which looks like that:

<somexml>
<item name="name1" />
<item name="name2" />
<item name="name3" />
<item name="name4" />
<item name="name5" />
<item name="name6" />
<item name="name7" />
<item name="name8" />
<item name="name9" />
</somexml>

and I have two XSL templates. First one should only be applied to the first <item>, and the second one should be applied to the rest of <item>s grouped by 3, also considering that the last group may (or may not) contain less than 3 elements. To make it more clear, I should get something like

<template1>name1</template1>
<template2>name2, name3, name4</template2>
<template2>name5, name6, name7</template2>
<template2>name8, name9</template2>

The main question is: is it even possible to achieve that using pure XSLT/XPath or should I fall back to grouping items in the backend code and just outputting them through different XLS templates? Sorry for not publishing my "what have I tried" - it was so ugly and I got rid of it as soon as I realized it would never work :)

هل كانت مفيدة؟

المحلول

The main question is: is it even possible to achieve that using pure XSLT/XPath

Yes, it is possible. But the output you request is not valid XML: you must have a root element.

XSLT 1.0

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

<xsl:template match="/somexml">
    <output>
        <xsl:apply-templates select="item[1]" />
        <xsl:apply-templates select="item[position() > 1][position() mod 3 = 1]" />
    </output>
</xsl:template>

<xsl:template match="item[1]">
    <template1><xsl:value-of select="@name"/></template1>
</xsl:template>

<xsl:template match="item">
    <template2>
        <xsl:value-of select="@name"/>
        <xsl:if test="following-sibling::item[1]">
            <xsl:text>,</xsl:text>
            <xsl:value-of select="following-sibling::item[1]/@name"/>
        </xsl:if>
        <xsl:if test="following-sibling::item[2]">
            <xsl:text>,</xsl:text>
            <xsl:value-of select="following-sibling::item[2]/@name"/>
        </xsl:if>
    </template2>
</xsl:template>

</xsl:stylesheet>

Note also that naming your result elements "template" is rather confusing in this context.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top