tags:

views:

45

answers:

1

I have the following XML file:

<Promotions>
  <Promotion>
    <Category>Arts &amp; Entertainment</Category>
    <Client>Client Five</Client>
    <Title>Get your Free 2</Title>
  </Promotion>
  <Promotion>
    <Category>Arts &amp; Entertainment</Category>
    <Client>Client 5</Client>
    <Title>Get your Free 4</Title>
  </Promotion>
  <Promotion>
    <Category>Arts &amp; Entertainment</Category>
    <Client>Client five</Client>
    <Title>Get your Free 5</Title>
  </Promotion>
  <Promotion>
    <Category>Community &amp; Neighborhood</Category>
    <Client>Client 1</Client>
    <Title>Get your Free 1</Title>
  </Promotion>
  <Promotion>
    <Category>Education</Category>
    <Client>Client 3</Client>
    <Title>Get Your Free 3</Title>
  </Promotion>

I would like to group by category. I tried the following and keep getting errors:

string  xslmarkup = @"
<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'&gt;
  <xsl:output method='html' />

  <xsl:key name='Categories' match='Promotions/Promotion' use='Category'/>

  <xsl:template match='/'>
    <xsl:apply-templates select='
      /Promotions/Promotion[
        generate-id() 
        = 
        generate-id(key ('Categories',Category)[1])
      ]
    '/>
  </xsl:template>

  <xsl:template match='Promotion'>
    <xsl:value-of select='Title'/>
  </xsl:template>
</xsl:stylesheet>
"

I would like something like this as the output:

    <h1>Arts &amp; Entertainment</h1>
    <ul>Client Five</ul>
    <ul>Get your Free 2</ul>

    <ul>Client 5</ul> 
    <ul>Get your Free 4</ul> 

    <ul>Client five</ul> 
    <ul>Get your Free 5</ul> 

    <h1>Community &amp; Neighborhood</h1> 
    <ul>Client 1</ul> 
    <ul>Get your Free 1</ul>

    <h1>Education</h1> 
    <ul>Client 3</ul> 
    <ul>Get Your Free 3</ul> 
+4  A: 

I think the error is your quoting but the logic appears flawed too. This isn't a pretty solution but it should get you on the right track.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
  <xsl:output method="xml" />
  <xsl:key name="categories" match="Category" use="." />
    <xsl:template match="/">
      <xsl:for-each select="/Promotions/Promotion/Category[
        generate-id(.) = generate-id(key('categories', .)[1])
      ]">
      <xsl:variable name="cname" select="." />
      <Category title="{.}">
        <xsl:for-each select="/Promotions/Promotion[Category=$cname]">
          <Title>
            <xsl:value-of select="Title" />
          </Title>
        </xsl:for-each>
      </Category>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

gives you this:

<Category title="Arts &amp; Entertainment">
  <Title>Get your Free 2</Title>
  <Title>Get your Free 4</Title>
  <Title>Get your Free 5</Title>
</Category>
<Category title="Community &amp; Neighborhood">
  <Title>Get your Free 1</Title>
</Category>
<Category title="Education">
  <Title>Get Your Free 3</Title>
</Category>
gum411
@gum411: Indent code blocks by four spaces (select text and press CTRL-K, or use the "010101" editor button). Edit your post to see what I mean.
Tomalak
+1 for the answer. Note that the `<xsl:for-each select="/Promotions/Promotion[Category=$cname]">` is equivalent to `<xsl:for-each select="key('Category', .)">`.
Tomalak
James Campbell
remove title="{.}" from the Category tag and use <Category><xsl:value-of select="."/></Category> instead.
gum411