0

I got the following xml:

<categories>
    <category>
        <id>1</id>
        <name>aaa</name>
                <url>lord</url>
        <categories>
            <category>
                <id>2</id>
                <name>bbb</name>
                                     <url>grrr</url>
            </category>
            <category>
                <id>3</id>
                <name>ccc</name>
                                     <url>grrr</url>
            </category>
        </categories>
    </category>
</categories>

What I need is to generate a html like:

<ul>
 <li>
  <a href="url">aaa</a>
  <ul>
   <li><a href="url">bbb</a></li>
   <li><a href="url">ccc</a></li>
  </ul> 
 </li>
<ul>

Any tip?

ps: I can have n category elements nested in the categories root, and n nested category elements inside each category.

2
  • Sounds like a job for XML StyleSheets! (dum-da-da-dum) Commented Nov 27, 2011 at 22:19
  • i didnt, im not really sure how can i do that. Commented Nov 27, 2011 at 22:32

3 Answers 3

3

Using XSLT, something like this should work:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt"
    exclude-result-prefixes="msxsl">
  <xsl:output method="html" indent="yes"/>

  <xsl:template match="categories">
    <ul>
      <xsl:apply-templates select="category"/>
    </ul>
  </xsl:template>

  <xsl:template match="category">
    <li>
      <a>
        <xsl:attribute name="href"><xsl:value-of select="url"/></xsl:attribute>
        <xsl:value-of select="name"/>
      </a>
      <xsl:apply-templates select="categories"/>
    </li>
  </xsl:template>
</xsl:stylesheet>

Which yields:

<ul>
  <li><a href="lord">aaa</a><ul>
      <li><a href="grrr">bbb</a></li>
      <li><a href="grrr">ccc</a></li>
    </ul>
  </li>
</ul>
Sign up to request clarification or add additional context in comments.

1 Comment

your code works fine. I changed my original post to put the url problem, I know its not something that i should put after, but the xls syntax its not clear for me, sorry and thx again.
3

Use XSLT - this answer does not need to be longer

3 Comments

I think it needs to be a bit longer. You should explain how this would be done with XSLT, and ideally give an example or link to a useful resource which gives tutorials in XLST.
Conciseness is better. Any good book in XSLT has that canonical example. Thanks. The tendency is to provide too much help. Someday I may need that level of help though.
You should have answered 'Go buy a book on XSLT'.
0

The preferred method is probably XSLT, but I'm quite partial to LINQ-to-XML because I can do it completely in code (no reference or dependence on an external XSLT document). Actually I just enjoy writing LINQ-to-XML a lot more than XSLT.

Here's an example of projecting your category node into a li node

private XElement ConvertCategoryToListItem(XElement category)
{
    // new list item using the 'name' element
    var result = new XElement("li", category.Element("name").Value);

    // add any sub-categories to an ul element
    if (category.Element("categories") != null)
    {
        var nestedCategories = category.Element("categories").Elements("category");
        result.Add(new XElement("ul"), nestedCategories.Select(c => 
            ConvertCategoryToListItem(c)));
    }
    return result;
}

I'd then call this on all the categories in your original XML.

new XElement("ul", this.input.Elements("category").Select(c => 
    ConvertCategoryToListItem(c)));

1 Comment

wow, thank you. very nice code. In my case scenario the user can change the html, so the xlst fits better! But I do prefer (like you) hard code everything when it applies.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.