ParseXML.py

Go to the documentation of this file.
00001 """
00002 Copyright 2008 Free Software Foundation, Inc.
00003 This file is part of GNU Radio
00004 
00005 GNU Radio Companion is free software; you can redistribute it and/or
00006 modify it under the terms of the GNU General Public License
00007 as published by the Free Software Foundation; either version 2
00008 of the License, or (at your option) any later version.
00009 
00010 GNU Radio Companion is distributed in the hope that it will be useful,
00011 but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 GNU General Public License for more details.
00014 
00015 You should have received a copy of the GNU General Public License
00016 along with this program; if not, write to the Free Software
00017 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
00018 """
00019 ##@package grc.gui.ParseXML
00020 #Parse xml files to nested data and vice-versa.
00021 #@author Josh Blum
00022 
00023 from lxml import etree
00024 from Utils import odict
00025 
00026 XMLSyntaxError = etree.XMLSyntaxError
00027 
00028 def validate_dtd(xml_file, dtd_file=None):
00029         """!
00030         Validate an xml file against its dtd.
00031         @param xml_file the xml file
00032         @param dtd_file the optional dtd file
00033         @throws Exception validation fails
00034         """
00035         if dtd_file:
00036                 dtd = etree.DTD(dtd_file)
00037                 xml = etree.parse(xml_file)
00038                 if not dtd.validate(xml.getroot()):
00039                         raise XMLSyntaxError, '\n'.join(map(str, dtd.error_log.filter_from_errors()))
00040         else:
00041                 parser = etree.XMLParser(dtd_validation=True)
00042                 xml = etree.parse(xml_file, parser=parser)
00043                 if parser.error_log:
00044                         raise XMLSyntaxError, '\n'.join(map(str, parser.error_log.filter_from_errors()))
00045 
00046 def from_file(xml_file):
00047         """!
00048         Create nested data from an xml file using the from xml helper.
00049         @param xml_file the xml file path
00050         @return the nested data
00051         """
00052         xml = etree.parse(xml_file).getroot()
00053         return _from_file(xml)
00054 
00055 def _from_file(xml):
00056         """!
00057         Recursivly parse the xml tree into nested data format.
00058         @param xml the xml tree
00059         @return the nested data
00060         """
00061         tag = xml.tag
00062         if not len(xml):
00063                 return odict({tag: xml.text or ''}) #store empty tags (text is None) as empty string
00064         nested_data = odict()
00065         for elem in xml:
00066                 key, value = _from_file(elem).items()[0]
00067                 if nested_data.has_key(key): nested_data[key].append(value)
00068                 else: nested_data[key] = [value]
00069         #delistify if the length of values is 1
00070         for key, values in nested_data.iteritems():
00071                 if len(values) == 1: nested_data[key] = values[0]
00072         return odict({tag: nested_data})
00073 
00074 def to_file(nested_data, xml_file):
00075         """!
00076         Write an xml file and use the to xml helper method to load it.
00077         @param nested_data the nested data
00078         @param xml_file the xml file path
00079         """
00080         xml = _to_file(nested_data)[0]
00081         open(xml_file, 'w').write(etree.tostring(xml, xml_declaration=True, pretty_print=True))
00082 
00083 def _to_file(nested_data):
00084         """!
00085         Recursivly parse the nested data into xml tree format.
00086         @param nested_data the nested data
00087         @return the xml tree filled with child nodes
00088         """
00089         nodes = list()
00090         for key, values in nested_data.iteritems():
00091                 #listify the values if not a list
00092                 if not isinstance(values, (list, set, tuple)):
00093                         values = [values]
00094                 for value in values:
00095                         node = etree.Element(key)
00096                         if isinstance(value, (str, unicode)): node.text = value
00097                         else: node.extend(_to_file(value))
00098                         nodes.append(node)
00099         return nodes
00100 
00101 if __name__ == '__main__':
00102         """Use the main method to test parse xml's functions."""
00103         pass

Generated on Sat Aug 23 02:00:11 2008 for GNU Radio Companion by  doxygen 1.5.4