Sunday, August 31, 2014

Python: Generate XML From Dictionary Or List


import sys
import tempfile
from XmlToDict import XmlParser

class DictToXml():
    def __init__(self, dic):
        self.dic = dic;
        self.str = "";
        self.NEW_LINE = "\n";
        self.attr = '<<attr>>';
        self.value = '<<value>>';

    def toXml(self):
        self.rx(self.dic);
        return self.str;

    def rx(self, o):
        w = 'rootTag'
        c = 1;
        self.str += "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>" + self.NEW_LINE;
        if type(o) == type([]):
            self.rxl(o, w, c);
        else:
            self.rxd(o, w, c);

    def rxd(self, o, w, c):
        self.str += self.tb(c - 1) + "<" + w;
        for k, o2 in o.iteritems():
            if k == self.attr:
                for k2, v2 in o2.iteritems():
                    self.str += " " + k2 + "=\"" + v2 + "\"";        
        ot = 0
        self.str += ">" + self.NEW_LINE;
        for k, o2 in o.iteritems():
            if k == self.attr:
                pass
            elif type(o2) == type ([]):
                self.rxl(o2, k, c + 1);
                ot = ot + 1;
            elif k == self.value:
                self.str = self.str[:-1]
                self.str += str(o2);
            elif type(o2) == type ({}):
                self.rxd(o2, k, c + 1);
                ot = ot + 1;
            else:                
                self.str += self.tb(c) + "<" + k + ">";
                self.str += str(o2);
                self.str += "</" + k + ">" + str(self.NEW_LINE);
                ot = ot + 1
        if ot == 0:
            self.str += self.tb(0) + "</" + w + ">" + str(self.NEW_LINE);
        else:
            self.str += self.tb(c - 1) + "</" + w + ">" + str(self.NEW_LINE);

    def rxl(self, o, w, c):
        for o2 in o:
            if type(o2) == type ({}):
                self.rxd(o2, w, c);
                #self.str += self.NEW_LINE;
            elif type(o2) == type ([]):
                self.str += self.tb(c - 1) + "<" + w + ">" + self.NEW_LINE;
                self.rxl(o2, w, c + 1);
                self.str += self.tb(c - 1) + "</" + w + ">" + self.NEW_LINE;
            else:
                self.str += self.tb(c - 1) + "<" + w + ">";
                self.str += str(o2);
                self.str += "</" + w + ">" + self.NEW_LINE;

    def tb(self, c):
        st = "";
        for num in range (0, c):
            st += str("    ");
        return st;
        
        
        
if __name__ == "__main__":
    dicobj = {}
    listobj = []
    list2 = []
    for num in range(1, 3):
        dicobj['key' + str(num)] = {};
        dicobj['key' + str(num)]['otherkey'] = str(num)
        dicobj['key' + str(num)]['<<attr>>'] = {}
        dicobj['key' + str(num)]['<<attr>>']['att1'] = 'att1: ' + str(num);
        dicobj['key' + str(num)]['<<attr>>']['att2'] = 'att2: ' + str(num);
        listobj.append(num)
        list2.append("LIST: " + str(num));
    for num in range(4, 6):
        dicobj['key' + str(num)] = {};
        dicobj['key' + str(num)]['<<value>>'] = str(num)
        dicobj['key' + str(num)]['<<attr>>'] = {}
        dicobj['key' + str(num)]['<<attr>>']['att1'] = 'att1: ' + str(num);
        dicobj['key' + str(num)]['<<attr>>']['att2'] = 'att2: ' + str(num);
        listobj.append(num)
        list2.append("LIST: " + str(num));
    listobj.append(list2)
    listobj.append({'nl': 'hmm', 'tl': 'just tl', '<<attr>>': {'att1': 'Att1'}});
    dicobj['list'] = listobj
    #print dicobj
    txml = DictToXml(dicobj).toXml()
    # printing xml string generated from data dictionary
    print txml
    print ''
    # saving xml string to a temporary file
    f = tempfile.NamedTemporaryFile(delete=False)
    f.write(txml);
    f.seek(0);
    f.close();

    # parsing the xml file using my XmlParser
    xmlObj = XmlParser(f.name);
    theXmlDictionary = xmlObj.parse()
    # priting the data dictionary as pretty format generated from xml
    xmlObj.printDic(theXmlDictionary);

    # again generating xml from data dictionary...
    print DictToXml(theXmlDictionary['rootTag']).toXml()

Output would be like this:


<?xml version="1.0" encoding="UTF-8" ?>
<rootTag>
    <key2 att2="att2: 2" att1="att1: 2">
        <otherkey>2</otherkey>
    </key2>
    <key1 att2="att2: 1" att1="att1: 1">
        <otherkey>1</otherkey>
    </key1>
    <list>1</list>
    <list>2</list>
    <list>4</list>
    <list>5</list>
    <list>
        <list>LIST: 1</list>
        <list>LIST: 2</list>
        <list>LIST: 4</list>
        <list>LIST: 5</list>
    </list>
    <list att1="Att1">
        <tl>just tl</tl>
        <nl>hmm</nl>
    </list>
    <key5 att2="att2: 5" att1="att1: 5">5</key5>
    <key4 att2="att2: 4" att1="att1: 4">4</key4>
</rootTag>


rootTag: {
   key2: {
      <<attr>>: {
         att2 :  att2: 2
         att1 :  att1: 2
      }
      otherkey :  2
   }
   key1: {
      <<attr>>: {
         att2 :  att2: 1
         att1 :  att1: 1
      }
      otherkey :  1
   }
   list: [
      0. 1
      1. 2
      2. 4
      3. 5
      4. {
         list: [
            0. LIST: 1
            1. LIST: 2
            2. LIST: 4
            3. LIST: 5
         ]
      }
      5. {
         <<attr>>: {
            att1 :  Att1
         }
         tl :  just tl
         nl :  hmm
      }
   ]
   key5: {
      <<attr>>: {
         att2 :  att2: 5
         att1 :  att1: 5
      }
      <<value>> :  5
   }
   key4: {
      <<attr>>: {
         att2 :  att2: 4
         att1 :  att1: 4
      }
      <<value>> :  4
   }
}
<?xml version="1.0" encoding="UTF-8" ?>
<rootTag>
    <key2 att2="att2: 2" att1="att1: 2">
        <otherkey>2</otherkey>
    </key2>
    <key1 att2="att2: 1" att1="att1: 1">
        <otherkey>1</otherkey>
    </key1>
    <list>1</list>
    <list>2</list>
    <list>4</list>
    <list>5</list>
    <list>
        <list>LIST: 1</list>
        <list>LIST: 2</list>
        <list>LIST: 4</list>
        <list>LIST: 5</list>
    </list>
    <list att1="Att1">
        <tl>just tl</tl>
        <nl>hmm</nl>
    </list>
    <key5 att2="att2: 5" att1="att1: 5">5</key5>
    <key4 att2="att2: 4" att1="att1: 4">4</key4>
</rootTag>

No comments:

Post a Comment