-1

I am trying to parse is xml

<a>
    <b Number="first">
        <c Over="1">
            <name>1</name>
        </c>
        <c Over="2">
            <name>2</name>
        </c>
    </b>
    <b Number="Second">
        <c Over="1">
            <name>3</name>
        </c>
        <c Over="2">
            <name>4</name>
        </c>
    </b>
</a>

using grouping concept

I do like this

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:ext="http://exslt.org/common" exclude-result-prefixes="ext">
    <xsl:key name="node-by-over" match="c" use="@Over" />

    <xsl:template match="a">

        <xsl:apply-templates select="b[@Number='first']/c[generate-id() = generate-id(key('node-by-over', @Over)[1])]"/>

    </xsl:template>

    <xsl:template match="c">
        <table id="">

            <xsl:for-each select="key('node-by-over', @Over)">
                <tr>
                    <td>balls:::<xsl:value-of select="name"/></td>

                </tr>
            </xsl:for-each>
        </table>
    </xsl:template>

</xsl:stylesheet>

my output

<table><tr><td>balls:::1</td></tr><tr><td>balls:::3</td></tr></table><table><tr><td>balls:::2</td></tr><tr><td>balls:::4</td></tr></table>

expected

<table><tr><td>balls:::1</td></tr><tr><td>balls:::2</td></tr></table>

why it is giving output like this 1,3,2,4 ??? I already use mention in applytemplateI need all c node which @Number is first

<xsl:apply-templates select="b[@Number='first']/c[generate-id() = generate-id(key('node-by-over', @Over)[1])]"/>

expected output 1,2 (parsing of name)

user5711656
  • 3,310
  • 4
  • 33
  • 70
  • It's not clear what you're trying to do. I suspect that your use of keys is unnecessarily complicated -- you mention that you _"need all `c` node which @Number is `first`"_, which could be done much more cleanly without using any keys at all. For your **expected** output, do you really just need the two `name` values contained within the topmost `b` element? – Eiríkr Útlendi Jun 01 '17 at 00:43
  • hi I able to solve my probm – user5711656 Jun 01 '17 at 01:16

1 Answers1

0

Your expected output indicates that you want to have:

  • a list of only the first c/name elements from each group (groupped by Over attribute),
  • in a single <table> element.

(You should have written the above in your post).

So the essential changes to your script boil down to the following:

  • Move <table> to match="a" template.
  • Delete <xsl:for-each in match="c" template (to generate the output for just the first element from the current group).

And here is the complete script:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes" omit-xml-declaration="yes"/>
  <xsl:key name="node-by-over" match="c" use="@Over" />

  <xsl:template match="a">
    <table>
      <xsl:apply-templates select=
        "b[@Number='first']/c[generate-id() =
        generate-id(key('node-by-over', @Over)[1])]"/>
    </table>
  </xsl:template>

  <xsl:template match="c">
    <tr><td>balls:::<xsl:value-of select="name"/></td></tr>
  </xsl:template>
</xsl:stylesheet>

Edit

Actually [@Number='first'] in select is not needed, as the grouping selects just the first c/name element from each group, (gathered from the whole document).

Or if some other mechanism has already groupped elements (into first and second group, maybe more), then the whole grouping based on key is not needed. Maybe just select="b[@Number='first']" would be enough.

Valdi_Bo
  • 30,023
  • 4
  • 23
  • 41