tags:

views:

1424

answers:

4

Hi,

I have seen many PHP function on how to generate a <ul><li> tag but my array input is quite complicated I guess. It is an array returned from a custom function called xml2assoc

My question is how can I convert the returned xml2assoc array result to a <ul><li> formatted HTML code using PHP.

Thanks.

$tree = array(
    0 => array(
     'tag' => 'NavigationMode',
     'value' => array(
      0 => array(
       'tag' => 'Title',
       'value' => 'Introduction'
      ),
      1 => array(
       'tag' => 'NavigationNode',
       'value' => array(
        0 => array(
         'tag' => 'Title',
         'value' => 'Sub Intro'
        )
       )
      )
     )
    ),
    1 => array(
     'tag' => 'NavigationMode',
     'value' => array(
      0 => array(
       'tag' => 'Title',
       'value' => 'Module 1'
      )
     )
    )
);

The final output that I need to generate is like this:

<ul>
    <li>
    Introduction
    <ul>
        <li>Sub Intro</li>
    </ul>
    </li>

    <li>Module 1</li>
</ul>
+3  A: 

If you have XML as input, why not use XSLT to transform it to <ul>?

I guess your input looks something like this (I assume "Navigation*M*ode" is a typo):

<tree>
  <NavigationNode>
    <title>Introduction</title>
    <NavigationNode>
      <title>Sub Intro</title>
    </NavigationNode>
  </NavigationNode>
  <NavigationNode>
    <title>Module 1</title>
  </NavigationNode>
</tree>

With a small XSLT 1.0 stylesheet:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;

  <xsl:output omit-xml-declaration="yes" indent="yes" />

  <xsl:template match="/tree">
    <ul>
      <xsl:apply-templates select="NavigationNode" />
    </ul>
  </xsl:template>

  <xsl:template match="NavigationNode">
    <li>
      <xsl:value-of select="title" />
      <xsl:if test="NavigationNode">
        <ul>
          <xsl:apply-templates select="NavigationNode" />
        </ul>
      </xsl:if>
    </li>
  </xsl:template>

</xsl:stylesheet>

This output is produced:

<ul>
  <li>
    Introduction
    <ul>
      <li>Sub Intro</li>
    </ul>
  </li>
  <li>Module 1</li>
</ul>

The PHP documentation shows how to use XSLT. It's simple.

Tomalak
A: 

Here is a quick PHP implementation for your array structure to get you started:

function create_html_list($nodes)
{
    echo '<ul>';

    foreach ($nodes as $node) {
        $childNodes = $node['value'];
        $titleNode = array_shift($childNodes);

        echo "<li>", $titleNode['value'];

        if (count($childNodes) > 0) {
            create_html_list($childNodes);
        }

        echo "</li>";
    }

    echo '</ul>';
}
Ferdinand Beyer
Thanks Ferdinand! :DThis one worked.
marknt15
A: 

Thanks Tomalak for your answer. I will try that out but first I need to edit this function (almost working). Can you help me out? Thanks again :D

function renderMenu($tree)
{
  foreach($tree as $item)
  {
    echo '<li><a href="'.$item['url'].'">';
    if(is_array($item['value']))
    {
      echo '<ul>';
      renderMenu($item['value']);
      echo '</ul>';
    }
    else if($item['tag'] === 'Title')
    {
      echo $item['value'] . ' dito';
    }
    echo '</a></li>';
  }
}

echo '<ul>'.renderMenu($tree).'</ul>';
marknt15
@marknt15: Please use actual comments to comment on an answer. You *can* post answers to your own question, but this post is not an answer and therefore you should delete it. Instead, you should edit your question itself to include additions or clarifications.
Tomalak
+1  A: 

i didn't test it for variations of the demo data ...

<?php

function getTitle($node) {
    foreach ($node['value'] as $cnode) {
            if ($cnode['tag'] == 'Title') {
                return $cnode['value'];
            }
    }

    return 'untitled';
}

function getCNodes($node) {
    $cnodes = array();

    foreach ($node['value'] as $cnode) {
        if ($cnode['tag'] == 'NavigationNode') {
            $cnodes[] = $cnode;
        }
    }

    return $cnodes;
}

function runTree($node) {
    $title  = getTitle($node);
    $cnodes = getCNodes($node);

    if (count($cnodes) > 0) {
        $out = '<li>' . $title . "\n" . '<ul>';
        foreach ($cnodes as $cnode) {
            $out .= runTree($cnode);
        }
        $out .= '</ul>' . "\n" . '</li>' . "\n";

        return $out;
    } else {
        return '<li>' . $title . '</li>' . "\n";
    }
}


$tree = array(
    0 => array(
        'tag' => 'NavigationMode',
        'value' => array(
                0 => array(
                        'tag' => 'Title',
                        'value' => 'Introduction'
                ),
                1 => array(
                        'tag' => 'NavigationNode',
                        'value' => array(
                                0 => array(
                                        'tag' => 'Title',
                                        'value' => 'Sub Intro'
                                )
                        )
                )
        )
    ),
    1 => array(
        'tag' => 'NavigationMode',
        'value' => array(
                0 => array(
                        'tag' => 'Title',
                        'value' => 'Module 1'
                )
        )
    )
);



echo '<ul>';
foreach ($tree as $node) {
    echo runTree($node);
}
echo '</ul>';

?>
Schnalle
Thanks this one works and has a correct nested HTML code :)
marknt15