0

I am creating a table using the following code based on the input provided in XML which is working perfectly fine but I want to convert to code to create a table dynamically meaning if i add more columns,code should automatically adjust..currently I have hardcoded that the table will contain four columns..please suggest on what changes need to be done to the code to achieve this

Input XML:-

<Fixes>
CR           FA      CL                    TITLE

409452      WLAN    656885        Age out RSSI values from buffer in Beacon miss scenario  
12345,45678  BT     54567,34567   Test
379104       BT     656928        CR379104: BT doesn’t work that Riva neither sends HCI Evt for HID ACL data nor response to HCI_INQUIRY after entering into pseudo sniff subrating mode.
</Fixes>

Python code

crInfo = [ ]
CRlist = [ ]
CRsFixedStart=xmlfile.find('<Fixes>')
CRsFixedEnd=xmlfile.find('</Fixes>')
info=xmlfile[CRsFixedStart+12:CRsFixedEnd].strip()
for i in info.splitlines():
    index = i.split(None, 3)
    CRlist.append(index)
crInfo= CRlisttable(CRlist)
file.close()

def CRlisttable(CRlist,CRcount):
#For logging
global logString
print "\nBuilding the CRtable\n"
logString += "Building the build combo table\n"
#print "CRlist"
#print CRlist
CRstring = "<table cellspacing=\"1\" cellpadding=\"1\" border=\"1\">\n"
CRstring += "<tr>\n"
CRstring += "<th bgcolor=\"#67B0F9\" scope=\"col\">" + CRlist[0][0] + "</th>\n"
CRstring += "<th bgcolor=\"#67B0F9\" scope=\"col\">" + CRlist[0][1] + "</th>\n"
CRstring += "<th bgcolor=\"#67B0F9\" scope=\"col\">" + CRlist[0][2] + "</th>\n"
CRstring += "<th bgcolor=\"#67B0F9\" scope=\"col\">" + CRlist[0][3] + "</th>\n"
CRstring += "</tr>\n"

TEMPLATE = """
<tr>
<td><a href='http://prism/CR/{CR}'>{CR}</a></td>
<td>{FA}</td>
<td>{CL}</td>
<td>{Title}</td>
</tr>
"""
for item in CRlist[1:]:
    CRstring += TEMPLATE.format(
        CR=item[0],
        FA=item[1],
        CL=item[2],
        Title=item[3],
        )
CRstring += "\n</table>\n"
#print CRstring
return CRstring
3
  • I suggest you try doing it yourself and then only post questions if you have a problem you can't figure out or want to know if there's a better way. Commented Nov 11, 2012 at 8:30
  • @martineau - Thats exaclty what I did here...I have a way which is working,I need some sample code or how can this be done dynamically?please let me know if you have any code-related suggestions Commented Nov 11, 2012 at 8:48
  • OK, basically every place that assumes there's a certain number of columns has to be changed to work with a variable number of them. This means no hardcoding things like 3 and writing out of all possibilities. The first order of business is to determine the number of columns that there are -- which you can do by seeing how many separate entries there are from the first row. You can also get their names so you know what to put in the TEMPLATE string which will also have to be dynamically created. Give that a shot. Commented Nov 11, 2012 at 10:44

2 Answers 2

3

Although I have some reservations about providing this since you seem unwilling to even attempt doing so yourself, here's an example showing one way it could be done -- all in the hopes that perhaps at least you'll be inclined to the effort to study and possibly learn a little something from it even though it's being handed to you...

with open('cr_fixes.xml') as file: # get some data to process
    xmlfile = file.read()

def CRlistToTable(CRlist):
    cols = CRlist[0] # first item is header-row of col names on the first line

    CRstrings = ['<table cellspacing="1" cellpadding="1" border="1">']
    # table header row
    CRstrings.append('  <tr>')
    for col in cols:
        CRstrings.append('    <th bgcolor="#67B0F9" scope="col">{}</th>'.format(col))
    CRstrings.append('  </tr>')

    # create a template for each table row
    TR_TEMPLATE = ['  <tr>']
    # 1st col of each row is CR and handled separately since it corresponds to a link
    TR_TEMPLATE.append(
        '    <td><a href="http://prism/CR/{{{}}}">{{{}}}</a></td>'.format(*[cols[0]]*2))
    for col in cols[1:]:
        TR_TEMPLATE.append('    <td>{{}}</td>'.format(col))
    TR_TEMPLATE.append('  </tr>')
    TR_TEMPLATE = '\n'.join(TR_TEMPLATE)

    # then apply the template to all the non-header rows of CRlist
    for items in CRlist[1:]:
        CRstrings.append(TR_TEMPLATE.format(CR=items[0], *items[1:]))
    CRstrings.append("</table>")

    return '\n'.join(CRstrings) + '\n'

FIXES_START_TAG, FIXES_END_TAG = '<Fixes>, </Fixes>'.replace(',', ' ').split()
CRsFixesStart = xmlfile.find(FIXES_START_TAG) + len(FIXES_START_TAG)
CRsFixesEnd = xmlfile.find(FIXES_END_TAG)
info = xmlfile[CRsFixesStart:CRsFixesEnd].strip().splitlines()

# first line of extracted info is a blank-separated list of column names
num_cols = len(info[0].split())

# split non-blank lines of info into list of columnar data
# assuming last col is the variable-length title, comprising reminder of line
CRlist = [line.split(None, num_cols-1) for line in info if line]

# convert list into html table
crInfo = CRlistToTable(CRlist)
print crInfo

Output:

<table cellspacing="1" cellpadding="1" border="1">
  <tr>
    <th bgcolor="#67B0F9" scope="col">CR</th>
    <th bgcolor="#67B0F9" scope="col">FA</th>
    <th bgcolor="#67B0F9" scope="col">CL</th>
    <th bgcolor="#67B0F9" scope="col">TITLE</th>
  </tr>
  <tr>
    <td><a href="http://prism/CR/409452">409452</a></td>
    <td>WLAN</td>
    <td>656885</td>
    <td>Age out RSSI values from buffer in Beacon miss scenario</td>
  </tr>
  <tr>
    <td><a href="http://prism/CR/12345,45678">12345,45678</a></td>
    <td>BT</td>
    <td>54567,34567</td>
    <td>Test</td>
  </tr>
  <tr>
    <td><a href="http://prism/CR/379104">379104</a></td>
    <td>BT</td>
    <td>656928</td>
    <td>CR379104: BT doesnt work that Riva neither sends HCI Evt for HID ACL data nor 
        response to HCI_INQUIRY after entering into pseudo sniff subrating mode.</td>
  </tr>
</table>

enter image description here

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

14 Comments

It's customary to also up-vote the answer you accept if you think it's worthy. Also, if you have questions about how any of the code works, feel free to ask. Thanks.
@martin-Thanks a lot,I didnt knew about the up-vote customary ,i just did it...above solution works perfectly fine but it has two drawbacks,issue1 is the links are created like prism/CR/12345,45678 if there are two entries in a CR cell,it should be like prism/CR/12345 and prism/CR/45678...bigger problem(issue #2) is, if one of the cells is empty,the title field gets preempted into the empty cell.... I am sorry I am not able to figure out a solution for these..can you guide me on this?
Thanks for up-voting too. Re: issue #1 -- if multiple CR values will always be comma-delimited, you could detect that and create multiple link entries. Issue #2 is tough because AFAIK the fields on each row are separated only by spaces. Something could probably be done if delimiters like tabs were used instead because otherwise it's difficult to detect missing columns. It would also allow you to have columns after TITLE.
Thanks for the quick response,seems like these two issues are quite challenging .. fields in each row can be seperated by a tab,I can enforce this in my script...
Also,the CR entries are always comma-delimited
|
0

That doesn't look like an XML file - it looks like a tab delimited CSV document within a pair of tags.

I suggest looking into the csv module for parsing the input file, and then a templating engine like jinja2 for writing the HTML generation.

Essentially - read in the csv, check the length of the headers (gives you number of columns), and then pass that data into a template. Within the template, you'll have a loop over the csv structure to generate the HTML.

3 Comments

i dont want to change my current code much unless its absolutely necessary...basically the data is pasted from an excel sheet into xml file but doesnt have to be always,it can be typed in xml file also..so we cannot always think it as a CSV document
But the data within the tag will always be csv-like. Read in the portion between the tags, load that bit of data into the csv module, and use it. You're going to need to change your code significantly to make it more generic. Also, avoid global! It is never a good idea.
FWIW, the input data doesn't look like it's tab delimited to me, although it would be nice if it was...

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.