How can I convert a .txt file to an xml file using python?

Latitude :23.1100348
Longitude:72.5364922
date&time :30:August:2014 05:04:31 PM
gsm cell id: 4993
Neighboring List- Lac : Cid : RSSI
15000     :    7072     :    25 dBm
15000     :    7073     :    23 dBm
15000     :    6102     :    24 dBm
15000     :    6101     :    24 dBm
15000     :    6103     :    17 dBm

Latitude :23.1120549
Longitude:72.5397988
date&time :30:August:2014 05:04:34 PM
gsm cell id: 4993
Neighboring List- Lac : Cid : RSSI
15000     :    7072     :    24 dBm
15000     :    7073     :    22 dBm
15000     :    6102     :    23 dBm
15000     :    6101     :    23 dBm
15000     :    2552     :    16 dBm

      

This is the my.txt file. I want to convert it to xml file like

<celldata>
<time>        </time>
<latitude>    </latitude>
<longitude>   </longitude>

</celldata>

      

I tried to list all components, but I didn't get o / pI want to keep all the latitude, longitude, gsm, time id values ​​in the list and this will add something like this to the xml file. I am writing below code.

import re

pa = 'Longitude|Latitude|gsm cell id|Neighboring List- Lac : Cid : RSSI'

with open('cell.txt','rw') as file:
    for line in file:
        line.strip()    
        if re.search(pa, line):
            lineInfo = line.split(':')
            title = lineInfo[0]
            value = lineInfo[1]

      

+3


source to share


1 answer


Try using the following code as a starter:

#!python3

import re
import xml.etree.ElementTree as ET

rex = re.compile(r'''(?P<title>Longitude
                       |Latitude
                       |date&time
                       |gsm\s+cell\s+id
                     )
                     \s*:?\s*
                     (?P<value>.*)
                     ''', re.VERBOSE)

root = ET.Element('root')
root.text = '\n'    # newline before the celldata element

with open('cell.txt') as f:
    celldata = ET.SubElement(root, 'celldata')
    celldata.text = '\n'    # newline before the collected element
    celldata.tail = '\n\n'  # empty line after the celldata element
    for line in f:
        # Empty line starts new celldata element (hack style, uggly)
        if line.isspace():
            celldata = ET.SubElement(root, 'celldata')
            celldata.text = '\n'
            celldata.tail = '\n\n'

        # If the line contains the wanted data, process it.
        m = rex.search(line)
        if m:
            # Fix some problems with the title as it will be used
            # as the tag name.
            title = m.group('title')
            title = title.replace('&', '')
            title = title.replace(' ', '')

            e = ET.SubElement(celldata, title.lower())
            e.text = m.group('value')
            e.tail = '\n'

# Display for debugging            
ET.dump(root)

# Include the root element to the tree and write the tree
# to the file.
tree = ET.ElementTree(root)
tree.write('cell.xml', encoding='utf-8', xml_declaration=True)

      

It displays your example data:

<root>
<celldata>
<latitude>23.1100348</latitude>
<longitude>72.5364922</longitude>
<datetime>30:August:2014 05:04:31 PM</datetime>
<gsmcellid>4993</gsmcellid>
</celldata>

<celldata>
<latitude>23.1120549</latitude>
<longitude>72.5397988</longitude>
<datetime>30:August:2014 05:04:34 PM</datetime>
<gsmcellid>4993</gsmcellid>
</celldata>

</root>

      

Update for the list of favorite neighbors:



#!python3

import re
import xml.etree.ElementTree as ET

rex = re.compile(r'''(?P<title>Longitude
                       |Latitude
                       |date&time
                       |gsm\s+cell\s+id
                       |Neighboring\s+List-\s+Lac\s+:\s+Cid\s+:\s+RSSI
                     )
                     \s*:?\s*
                     (?P<value>.*)
                     ''', re.VERBOSE)

root = ET.Element('root')
root.text = '\n'    # newline before the celldata element

with open('cell.txt') as f:
    celldata = ET.SubElement(root, 'celldata')
    celldata.text = '\n'    # newline before the collected element
    celldata.tail = '\n\n'  # empty line after the celldata element
    for line in f:
        # Empty line starts new celldata element (hack style, uggly)
        if line.isspace():
            celldata = ET.SubElement(root, 'celldata')
            celldata.text = '\n'
            celldata.tail = '\n\n'
        else:
            # If the line contains the wanted data, process it.
            m = rex.search(line)
            if m:
                # Fix some problems with the title as it will be used
                # as the tag name.
                title = m.group('title')
                title = title.replace('&', '')
                title = title.replace(' ', '')

                if line.startswith('Neighboring'):
                    neighbours = ET.SubElement(celldata, 'neighbours')
                    neighbours.text = '\n'
                    neighbours.tail = '\n'
                else:
                    e = ET.SubElement(celldata, title.lower())
                    e.text = m.group('value')
                    e.tail = '\n'
            else:
                # This is the neighbour item. Split it by colon,
                # and set the attributes of the item element.
                item = ET.SubElement(neighbours, 'item')
                item.tail = '\n'

                lac, cid, rssi = (a.strip() for a in line.split(':'))
                item.attrib['lac'] = lac
                item.attrib['cid'] = cid
                item.attrib['rssi'] = rssi.split()[0] # dBm removed

# Include the root element to the tree and write the tree
# to the file.
tree = ET.ElementTree(root)
tree.write('cell.xml', encoding='utf-8', xml_declaration=True)

      

An update to accept an empty string before neighbors is also a more efficient implementation for general purposes:

#!python3

import re
import xml.etree.ElementTree as ET

rex = re.compile(r'''(?P<title>Longitude
                       |Latitude
                       |date&time
                       |gsm\s+cell\s+id
                       |Neighboring\s+List-\s+Lac\s+:\s+Cid\s+:\s+RSSI
                     )
                     \s*:?\s*
                     (?P<value>.*)
                     ''', re.VERBOSE)

root = ET.Element('root')
root.text = '\n'    # newline before the celldata element

with open('cell.txt') as f:
    celldata = ET.SubElement(root, 'celldata')
    celldata.text = '\n'    # newline before the collected element
    celldata.tail = '\n\n'  # empty line after the celldata element
    status = 0              # init status of the finite automaton
    for line in f:
        if status == 0:     # lines of the heading expected
            # If the line contains the wanted data, process it.
            m = rex.search(line)
            if m:
                # Fix some problems with the title as it will be used
                # as the tag name.
                title = m.group('title')
                title = title.replace('&', '')
                title = title.replace(' ', '')

                if line.startswith('Neighboring'):
                    neighbours = ET.SubElement(celldata, 'neighbours')
                    neighbours.text = '\n'
                    neighbours.tail = '\n'
                    status = 1  # empty line and then list of neighbours expected
                else:
                    e = ET.SubElement(celldata, title.lower())
                    e.text = m.group('value')
                    e.tail = '\n'
                    # keep the same status

        elif status == 1:   # empty line expected
            if line.isspace():
                status = 2  # list of neighbours must follow
            else:
                raise RuntimeError('Empty line expected. (status == {})'.format(status))
                status = 999 # error status

        elif status == 2:   # neighbour or the empty line as final separator

            if line.isspace():
                celldata = ET.SubElement(root, 'celldata')
                celldata.text = '\n'
                celldata.tail = '\n\n'
                status = 0  # go to the initial status
            else:
                # This is the neighbour item. Split it by colon,
                # and set the attributes of the item element.
                item = ET.SubElement(neighbours, 'item')
                item.tail = '\n'

                lac, cid, rssi = (a.strip() for a in line.split(':'))
                item.attrib['lac'] = lac
                item.attrib['cid'] = cid
                item.attrib['rssi'] = rssi.split()[0] # dBm removed
                # keep the same status

        elif status == 999: # error status -- break the loop
            break

        else:
            raise LogicError('Unexpected status {}.'.format(status))
            break

# Display for debugging
ET.dump(root)

# Include the root element to the tree and write the tree
# to the file.
tree = ET.ElementTree(root)
tree.write('cell.xml', encoding='utf-8', xml_declaration=True)

      

The code implements a so-called state machine, where a variable status

represents its current status. You can visualize it with a pencil and draw small circles with value numbers inside (called nodes in graph theory). While in status, you only allow some kind of input ( line

). When the input is recognized, you draw an arrow (directed edge in graph theory) to a different state (possibly with the same status as the loop traversing back to the same node). Arrow is annotated with `condition | act".

The result can look complicated in the beginning; however, it is easy in the sense that you can always focus on the part of the code that belongs to a certain status. And also the code can be easily changed. However, finite state machines have limited power. But they are just perfect for such problems.

+3


source







All Articles