X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FxmlManager.py;h=4b4fa61cfc08152cc98c29eb82b9f17756859910;hb=a89eafdc38170b5901d3ce60664c5c37214160a7;hp=ad454d8b6e9b313beea9e742d26067179434871e;hpb=2f5963f6298668374d3236955e3c28cc9af48711;p=tools%2Fsat.git diff --git a/src/xmlManager.py b/src/xmlManager.py index ad454d8..4b4fa61 100644 --- a/src/xmlManager.py +++ b/src/xmlManager.py @@ -17,12 +17,21 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA import os -import re +import shutil + +try: # For python2 + import sys + reload(sys) + sys.setdefaultencoding('utf8') +except: + pass import src -from . import ElementTree as etree +import src.ElementTree as etree + +verbose = False -class xmlLogFile(object): +class XmlLogFile(object): '''Class to manage writing in salomeTools xml log file ''' def __init__(self, filePath, rootname, attrib = {}): @@ -30,39 +39,49 @@ class xmlLogFile(object): :param filePath str: The path to the file where to write the log file :param rootname str: The name of the root node of the xml file - :param attrib dict: the dictionary that contains the attributes and value of the root node + :param attrib dict: the dictionary that contains the attributes + and value of the root node ''' - # Initialize the filePath and ensure that the directory that contain the file exists (make it if necessary) + # Initialize the filePath and ensure that the directory + # that contain the file exists (make it if necessary) self.logFile = filePath src.ensure_path_exists(os.path.dirname(filePath)) # Initialize the field that contain the xml in memory self.xmlroot = etree.Element(rootname, attrib = attrib) - - def write_tree(self, stylesheet=None): + + def write_tree(self, stylesheet=None, file_path = None): '''Write the xml tree in the log file path. Add the stylesheet if asked. :param stylesheet str: The stylesheet to apply to the xml file ''' - f = open(self.logFile, 'w') - f.write("\n") - if stylesheet: - f.write("\n" % stylesheet) - f.write(etree.tostring(self.xmlroot, encoding='utf-8')) - f.close() + log_file_path = self.logFile + if file_path: + log_file_path = file_path + try: + with open(log_file_path, 'w') as f: + f.write("\n") + if stylesheet: + f.write("\n" % stylesheet) + pass + res= etree.tostring(self.xmlroot, encoding='utf-8') + f.write(res) + except IOError: + pass def add_simple_node(self, node_name, text=None, attrib={}): '''Add a node with some attibutes and text to the root node. :param node_name str: the name of the node to add :param text str: the text of the node - :param attrib dict: the dictionary containing the attribute of the new node + :param attrib dict: the dictionary containing the + attribute of the new node ''' n = etree.Element(node_name, attrib=attrib) n.text = text self.xmlroot.append(n) return n - def append_node(self, node_name, text): + def append_node_text(self, node_name, text): '''Append a new text to the node that has node_name as name :param node_name str: The name of the node on which append text @@ -74,7 +93,15 @@ class xmlLogFile(object): # append the text field.text += text -class readXmlFile(object): + def append_node_attrib(self, node_name, attrib): + '''Append a new attributes to the node that has node_name as name + + :param node_name str: The name of the node on which append text + :param attrib dixt: The attrib to append + ''' + self.xmlroot.find(node_name).attrib.update(attrib) + +class ReadXmlFile(object): '''Class to manage reading of an xml log file ''' def __init__(self, filePath): @@ -85,58 +112,153 @@ class readXmlFile(object): self.filePath = filePath etree_inst = etree.parse(filePath) self.xmlroot = etree_inst.parse(filePath) + + def getRootAttrib(self): + '''Get the attibutes of the self.xmlroot + + :return: The attributes of the root node + :rtype: dict + ''' + return self.xmlroot.attrib - def get_attrib_text(self, attribname): - '''Parse the root nodes and get all node that have the attribname. Return the list of [(value of attribname, text), ...] + def get_attrib(self, node_name): + '''Get the attibutes of the node node_name in self.xmlroot + + :param node_name str: the name of the node + :return: the attibutes of the node node_name in self.xmlroot + :rtype: dict ''' - lres = [] - # Loop on all root nodes - for field in self.xmlroot: - if attribname in field.attrib: - lres.append((field.attrib[attribname], field.text)) - return lres + attrib = self.xmlroot.find(node_name).attrib + # To be python 3 compatible, convert bytes to str if there are any + fixedAttrib = {} + for k in attrib.keys(): + if isinstance(k, bytes): + key = k.decode() + else: + key = k + if isinstance(attrib[k], bytes): + value = attrib[k].decode() + else: + value = attrib[k] + fixedAttrib[key] = value + return fixedAttrib def get_node_text(self, node): - '''Get the text of the first node that has name that corresponds to the parameter node + '''Get the text of the first node that has name + that corresponds to the parameter node :param node str: the name of the node from which get the text + :return: the text of the first node that has name + that corresponds to the parameter node + :rtype: str ''' - # Loop on all root nodes - for field in self.xmlroot: - if field.tag == node: - return field.text - return '' + return self.xmlroot.find(node).text + +def add_simple_node(root_node, node_name, text=None, attrib={}): + '''Add a node with some attibutes and text to the root node. + :param root_node etree.Element: the Etree element where to add the new node + :param node_name str: the name of the node to add + :param text str: the text of the node + :param attrib dict: the dictionary containing the + attribute of the new node + ''' + n = etree.Element(node_name, attrib=attrib) + n.text = text + root_node.append(n) + return n -def update_hat_xml(logDir, application=None): - '''Create the xml file in logDir that contain all the xml file and have a name like YYYYMMDD_HHMMSS_namecmd.xml +def append_node_attrib(root_node, attrib): + '''Append a new attributes to the node that has node_name as name - :param logDir str: the directory to parse - :param application str: the name of the application if there is any + :param root_node etree.Element: the Etree element + where to append the new attibutes + :param attrib dixt: The attrib to append ''' - # Create an instance of xmlLogFile class to create hat.xml file - xmlHatFilePath = os.path.join(logDir, 'hat.xml') - # If there is an application, add the attribute to the root node - if application: - xmlHat = xmlLogFile(xmlHatFilePath, "LOGlist", {"application" : application}) - else: - xmlHat = xmlLogFile(xmlHatFilePath, "LOGlist", {"application" : "NO"}) + root_node.attrib.update(attrib) + +def find_node_by_attrib(xmlroot, name_node, key, value): + '''Find the nfirst ode from xmlroot that has name name_node and that has in + its attributes {key : value}. Return the node - # parse the log directory to find all the command logs, then add it to the xml file - for fileName in os.listdir(logDir): - # YYYYMMDD_HHMMSS_namecmd.xml - sExpr = "^[0-9]{8}_+[0-9]{6}_+.*.xml$" - oExpr = re.compile(sExpr) - if oExpr.search(fileName): - # get date and hour and format it - date_hour_cmd = fileName.split('_') - date_not_formated = date_hour_cmd[0] - date = "%s/%s/%s" % (date_not_formated[6:8], date_not_formated[4:6], date_not_formated[0:4] ) - hour_not_formated = date_hour_cmd[1] - hour = "%s:%s:%s" % (hour_not_formated[0:2], hour_not_formated[2:4], hour_not_formated[4:6]) - cmd = date_hour_cmd[2][:-len('.xml')] - # add a node to the hat.xml file - xmlHat.add_simple_node("LogCommand", text=fileName, attrib = {"date" : date, "hour" : hour, "cmd" : cmd}) + :param xmlroot etree.Element: the Etree element where to search + :param name_node str: the name of node to search + :param key str: the key to search + :param value str: the value to search + :return: the found node + :rtype: xmlroot etree.Element + ''' + l_nodes = xmlroot.findall(name_node) + for node in l_nodes: + if key not in node.attrib.keys(): + continue + if node.attrib[key] == value: + return node + return None + + +def write_report(filename, xmlroot, stylesheet): + """Writes a report file from a XML tree. + + :param filename str: The path to the file to create + :param xmlroot etree.Element: the Etree element to write to the file + :param stylesheet str: The stylesheet to add to the begin of the file + """ + dirname = os.path.dirname(filename) + if not os.path.exists(dirname): + os.makedirs(dirname) + if len(stylesheet) > 0: + styleName = stylesheet + else: + styleName = None + + with open(filename, "w") as f: + f.write("\n") + if styleName is not None: + f.write("\n" % styleName) + res = etree.tostring(xmlroot, encoding='utf-8') + # print("********** etree.tostring %s" % res) + f.write(res) + + # create fileStyle in dirname if not existing + if styleName is not None: + styleFile = os.path.join(dirname, styleName) + if not os.path.exists(styleFile): + # copy if from "salomeTools/src/xsl" + srcdir = os.path.dirname(src.__file__) + srcFile = os.path.join(srcdir, "xsl", styleName) + if verbose: print("write_report %s style %s" % (srcFile, styleFile)) + shutil.copy(srcFile, dirname) + +def escapeSequence(aStr): + """ + See xml specification: + The ampersand character(&) and the left angle bracket(<) MUST NOT appear in their + literal form, except when used as markup delimiters, or within a comment, a processing + instruction, or a CDATA section. + If they are needed elsewhere, they MUST be escaped using either numeric character references + or the strings '&' and '<' respectively. + The right angle bracket(>) may be + represented using the string '>', and MUST, + for compatibility, be escaped using either '>' or a character reference + when it appears in the string " ]]> " in content, + when that string is not marking the end of a CDATA section. + You can use these escape sequences: + < (less - than) as < or < + > (greater - than) as > or > + & (ampersand) as & + ' (apostrophe or single quote) as ' + " (double-quote) as " + """ + replaces = [ ('&', '&'), + ('>', '>'), + ('<', '<'), + ("'", '''), + ('"', '"'), + ] + res = aStr + for ini, fin in replaces: # order matters + res = res.replace(ini, fin) + return res + - # Write the file on the hard drive - xmlHat.write_tree('hat.xsl') \ No newline at end of file