How to generate a <ul><li> tree without recursive using python or other language?
class tree:
def __init__(se开发者_如何学编程lf, name='a', childs=[]):
self.name = name
self.childs = childs
output:
<ul>
<li>
Introduction
<ul>
<li>Sub Intro</li>
</ul>
</li>
<li>Module 1</li>
</ul>
To generate nested lists without recursion you'd simply keep track of your nesting level, incrementing it as you traverse into deeper levels of nesting and decrementing it as you traverse back upwards.
The natural approach, for handling things like closing tags, would be to maintain a simple stack (Python list) and push the closing tags onto it as you insert their corresponding opening tags into the output stream. You'd then pop these off as you traverse out of any level of nesting.
You don't say anything about your input format ... so let's pretend that it looks something like:
= Introduction
== Sub Intro
= Module 1
Then something like:
def pref_txt_to_ul(txt):
nesting = 0
closing_tags = list()
for x in txt:
if len(x.split()) < 2:
continue
prefix, content = x.split(None,1)
nd = len(prefix) ## new depth
assert prefix == "=" * nd ## First "word" is all = characters
if nd > nesting:
print "\n", " " * nesting * 4, "<ul>" * (nd - nesting), ## Push new opening tags into output
closing_tags.append('</ul>' * (nd - nesting)) ## push closing tags for later
elif nd < nesting:
for x in range(nesting - nd):
if closing_tags:
print " " * nesting * 4, closing_tags.pop(), ## Pop closing tags
nesting = nd
print "\n", " " * nesting * 4, "<li>%s</li>" % content, # push out this item (at new depth)
## After all text is done:
while closing_tags:
print closing_tags.pop(), # Pop off remaining cloing tags
... should do the trick (albeit, rather crudely).
Note that I'm not actually enforcing a rule that one should only increase the nesting level in increments of one. Degenerate input that go from = to ====== in one step would generate extraneous tags and push extraneous tags into the closing stack.
Note: I'm only answering the explicit question about how to handle nesting without recursion. One might infer from your example (using HTML unordered list tags) that your real goal is to generate valid HTML. In that case there are a wealth of Python tools that are far better suited to that task then any crude text munging I'm doing in this example. A Yahoo or Google search on: Python "generate HTML" will return many thousands of pages about ways to do this and the many available tools for this.
(I remember that I used HTMLgen years ago, and I see that it's still available as a Debian package, but it seems to have fallen off of PyPI ... the Python Package Index. There are undoubtedly much more recently updated packages out there. Most people seem to use templating engines such as Genshi or Mako, for example).
Maybe something like this:
NEW=object()
END=object()
class tree:
def __init__(self, name='a', childs=[]):
self.name = name
self.childs = childs
def __str__(self):
indent=0
result=[]
for i in self.childs:
if i is NEW:
result.append('%s<ul>\n'%(' '*indent))
indent+=1
elif i is END:
indent-=1
result.append('%s</ul>\n'%(' '*indent))
else:
result.append('%s<li>%s</li>\n'%(' '*indent, i))
return ''.join(result)
print tree('test', [NEW, 'Introduction', NEW, 'Sub Intro', END, 'Module 1', END])
精彩评论