Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting a list into XML

For a project I'm currently working on, I'm given an array of objects, each of which contain a "content" property and a "level" property. I need to convert this list into an HTML bulleted list. For example, if I was given the following input (shown in JSON for simplicity):

[ {content: "Hey", level: "1"},
  {content: "I just met you", level: "2"},
  {content: "and this is crazy", level: "2"},
  {content: "but here's my number", level: "1"},
  {content: "call me, maybe", level: "3"} ]

I would need to convert it to the following XHTML:

<ul>
  <li>Hey</li>
  <li>
    <ul>
      <li>I just met you</li>
      <li>and this is crazy</li>          
    </ul>
  </li>
  <li>but here's my number</li>
  <li>
    <ul>
      <li>
        <ul>
          <li>call me, maybe</li>      
        </ul>
      </li>
    </ul>
  </li>
</ul>

The end product would look like this:

  • Hey
    • I just met you
    • and this is crazy
  • but here's my number
    • call me, maybe (<- one level deeper - I don't think I can do this in SO)

Kind of a weird puzzle. Any suggestions as to an algorithm/approach that would be most efficient/easy to implement? I'm implementing this in C#, but an example/idea in another language would be more than welcome.

like image 923
Nathan Friend Avatar asked Nov 03 '22 18:11

Nathan Friend


1 Answers

The idea here is that as long as the level is greater than or equal to the previous, it should be nested, and if it is lesser, than it should be closed.

public string BuildLists(List<KeyValuePair<string, int>> pairs)
{
    int CurrentLevel = 1;
    StringBuilder s = new StringBuilder();

    s.Append("<ul>");

    foreach (KeyValuePair<string, int> pair in pairs)
    {
        if(pair.Value > CurrentLevel)
        {
            //Nest more
            for(int i = 0; i < pair.Value - CurrentLevel; i++)
            {
                s.Append("<li><ul>");
            }
        }
        else if(pair.Value < CurrentLevel)
        {
            //Close Tags
            for(int i = 0; i < CurrentLevel - pair.Value; i++)
            {
                s.Append("</ul></li>");
            }
        }

        s.Append("<li>" + pair.Key + "</li>");

        CurrentLevel = pair.Value
    }

    //Close everything.
    for(int i = 0; i < CurrentLevel - 1; i++)
    {
        s.Append("</ul></li>");
    }

    s.Append("</ul>");
    return s.ToString();
}
like image 153
HenryZhang Avatar answered Nov 09 '22 07:11

HenryZhang