0

I want to create html output from array

But I could not completed the code. Are there any one who can complete.

Or are there any better idea to write this code?

$schema = array(
    0 => array(
        'tag' => 'div',
        'class' => 'lines',
        0 => array(
            'tag' => 'div',
            0 => array(
                'tag' => 'span',
                'key' => 'Product Name'
            ),
            'val' => 'Soap'
        )
        1 => array(
            'tag' => 'div',
            0 => array(
                'tag' => 'span',
                'key' => 'Product Name'
            ),
            'val' => 'Ball'
        )
    )
);

function get_output($schema){
    foreach($schema as $k => $v){
        if(is_array($v)){
            $v = get_output($v);
        }else{
            $info = '<$tag $att>$key</$tag>';
            if($k == 'tag'){ $info = str_replace('$tag',$v,$info); }
            if($k == 'class'){ $info = str_replace('$att','"'.$v.'" $att',$info); }
        }
    }
    return $info;
}

echo get_output($schema);

Expected Output is

<div class="lines">
    <div><span>Product Name</span>Soap</div>
    <div><span>Pruduct Name</span>Ball</div>
</div><!-- #lines -->

UPDATE 1

Is it possible to create same function for following array..

$schema = array(
    'div' => array(
        'class' => 'lines',
        'div' => array(
             'span' => array(
                'key' => 'Product Name'
            ),
            'val' => 'Soap'
        ),
        'div' => array(
             'span' => array(
                'key' => 'Product Name'
            ),
            'val' => 'Ball'
            )
        )
);

UPDATE 2

What about that one?

$schema = array(
    'div' => array(
        'class' => 'lines',
        'div' => array(
             'span' => array(
                'key' => 'Product Name'
            ),
            'val' => 'Soap'
        ),
        'layer' => array(
             'span' => array(
                'key' => 'Product Name'
            ),
            'val' => 'Ball'
            )
        )
);

1 Answer 1

0

A simple recursive tree renderer can be implemented like this...

<?php

$schema = array(
array(
    'tag' => 'div',
    'class' => 'lines',
    array(
        'tag' => 'div',
         array(
            'tag' => 'span',
            'key' => 'Product Name'
        ),
        'val' => 'Soap'
    ),
     array(
        'tag' => 'div',
         array(
            'tag' => 'span',
            'key' => 'Product Name'
        ),
        'val' => 'Ball'
        )
    )
);

function get_output($schema){
    $tag = "";
    $attribs = array();
    $children = array();
    foreach($schema as $k => $v){        
        if(is_array($v)){
            $children[] = get_output($v);
        } else {
            switch($k){
                case "tag":
                    $tag = $v;
                    break;
                case "val":
                case "key":
                    $children[] = $v;
                    break;
                default:
                    $attribs[$k] = $v;
                    break;
            }
        }    
    }
    $str= "";
    if ($tag){
        $str = "<$tag";
        foreach($attribs as $k=>$v){
            $str.= " $k=\"".urlencode($v)."\"";
        }
        $str.= ">";
    }
    foreach($children as $child){
        $str.=$child;    
    }
    if ($tag){
        $str.= "</".$tag.">";
    }
    return $str;

}

echo get_output($schema);

Outputs

<div class="lines"><div><span>Product Name</span>Soap</div><div><span>Product Name</span>Ball</div></div>

To answer your updated question if duplicate sibling tags cannot happen then reimplementing your get_output function like:

function get_output($schema, $tag = false){
    $attribs = array();
    $children = array();
    foreach($schema as $k => $v){        
        if(is_array($v)){
            $children[] = get_output($v, $k);
        } else {
            switch($k){
                case "val":
                case "key":
                    $children[] = htmlspecialchars($v);
                    break;
                default:
                    $attribs[$k] = $v;
                    break;
            }
        }    
    }
    echo $tag; print_r($children); print_r($attribs);
    $str= "";
    if ($tag){
        $str = "<$tag";
        foreach($attribs as $k=>$v){
            $str.= " $k=\"".urlencode($v)."\"";
        }
        $str.= ">";
    }
    foreach($children as $child){
        $str.=$child;    
    }
    if ($tag){
        $str.= "</".$tag.">";
    }
    return $str;

}

Should get you where you need to be.

10
  • Orangepill this is lightening speed answer. This is perfect solution.. Is it possible to create same output from UPDATED array structure? With names Commented Aug 22, 2013 at 16:43
  • 1
    @DenizPorsuk Your array won't work in the updated example... there are two keys named div. Commented Aug 22, 2013 at 16:55
  • You are totally right. I changed the code. Could it be for UPDATE 2 Commented Aug 22, 2013 at 17:04
  • I want to have smallest array as much as possible. Commented Aug 22, 2013 at 17:05
  • @DenizPorsuk Your first approach was the sanest. Given layer as an associative key how would one know that it's supposed to be a div? Commented Aug 22, 2013 at 17:27

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.