4
<ul id='parent_of_all'>
<li>
  <span class='operator'>&&</span>
  <ul>
    <li>
      <span class='operator'>||</span>
      <ul>
        <li>
          <span class='operator'>&&</span>
          <ul>
            <li>
            <span class='condition'>1 == 1</span>
            </li>
          </ul>
        </li>
      </ul>
    </li>
  </ul>
  <ul>
    <li>
      <span class='condition'>1 != 0</span>
    </li>
  </ul>
</li>
</ul>

to

{"&&":[{'||':[ {'&&':[ {"lhs": "1", "comparator": "==", "rhs":"1"} ]} ] } , {"lhs": "1", "comparator": "!=", "rhs":"0"}]}

As of now, I know the basics of jQuery, JavaScript. I need to know where to start thinking in order to accomplish the above conversion.

And the html tree could be more complex with more children.

3 Answers 3

1

You can do this with each and map

var obj = {}
var span = $('li > span').not('ul li span').text();

$('ul li span').each(function() {
 var text = $(this).text().split(' ');
 obj[span] = (obj[span]||[]).concat({lhs: text[0], comparator: text[1], rhs: text[2]});
});

console.log(obj)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<li>
  <span>&&</span>
  <ul>
    <li>
      <span>1 == 1</span>
    </li>
  </ul>
  <ul>
    <li>
      <span>1 != 0</span>
    </li>
  </ul>
</li>

Sign up to request clarification or add additional context in comments.

1 Comment

your implementation is same as Alexandru's and is limited to one level of tree. So if i add a child at nth level, your code appends to the root parent but not immediate parent
1

You will need a way to select the first level of li, I assumed you have a parent element with an id such as list. I wrote the following code using basic jquery so you can understand it.

var result = {};

var $all_li = $('#list').children('li');     // selecting the first level of li
for(var i in $all_li){                       // iterating all_li using for (you may use forEach )  

    var $current_li = $( $all_li[i] );                       // getting operator from first span
    var operator = $current_li.children('span').html();      // the text of the operator

    var $inner_spans = $current_li.find('>ul >li >span');    // getting list of children spans (from path $list>li>ul>li>span)
    var li_spans = [];                                       // an array where we will put the inner span objects
    for(var j in $inner_spans){ // iterating the inner spans
        var text = $($inner_spans[j]).html().split(" ");     // splitting the html
        li_spans.push({
            lhs: text[0],
            comparator: text[1],
            rhs: text[2]
        });                                // adding the splitted html to an object. Note: error if text didn't have 2 white spaces
    }

    result[operator] = li_spans;          // adding the operator key and li_spans value to the result json
}

This code will parse the html and construct the result json, it should work for the html format you provided. Keep in mind that it does not handle errors (such as bad tree format). simmiar html formats.

3 Comments

Thanks for giving a start. But your implementation is limited to one level of tree. So if i add a child at nth level, your code appends to the root parent but not immediate parent.
@bill_cosby You gave a very specific html structure and from your example we can't understant how the result should look like.
Sorry about that. But I did mention that the tree could be complex. I just made an edit.
0

Thanks @Alexandru and @Nenad for giving a start. I have been able to complete this on my own. Below is the function that generates json.

function prepare_json(current_node){
    var object = {}
    var span = $(current_node).children('span')
    if (span.hasClass('condition')){
        var text = span.html().split(" ");
        object = {lhs: text[0], comparator: text[1], rhs: text[2]}
    }
    else if(span.hasClass('operator')){
        var operator = span.text()
        object[operator] = (object[operator] || [])
        var children = $(current_node).children('ul').children('li')
        for(var i = 0; i < children.length; i++){
            var child_pql = prepare_json([children[i]])
            object[operator].push(child_pql)
        }
    }
    return object
}

Below is the code that calls that function:

var parent_node = $('#parent_of_all').children('li')
var json = JSON.stringify(prepare_pql_json(parent_node), null, 2)

Comments

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.