Salome HOME
add history in job reports
[tools/sat.git] / src / xmlManager.py
1 #!/usr/bin/env python
2 #-*- coding:utf-8 -*-
3 #  Copyright (C) 2010-2013  CEA/DEN
4 #
5 #  This library is free software; you can redistribute it and/or
6 #  modify it under the terms of the GNU Lesser General Public
7 #  License as published by the Free Software Foundation; either
8 #  version 2.1 of the License.
9 #
10 #  This library is distributed in the hope that it will be useful,
11 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 #  Lesser General Public License for more details.
14 #
15 #  You should have received a copy of the GNU Lesser General Public
16 #  License along with this library; if not, write to the Free Software
17 #  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
18
19 import os
20 try: # For python2
21     import sys
22     reload(sys)  
23     sys.setdefaultencoding('utf8')
24 except:
25     pass
26
27 import src
28 from . import ElementTree as etree
29
30 class XmlLogFile(object):
31     '''Class to manage writing in salomeTools xml log file
32     '''
33     def __init__(self, filePath, rootname, attrib = {}):
34         '''Initialization
35         
36         :param filePath str: The path to the file where to write the log file
37         :param rootname str: The name of the root node of the xml file
38         :param attrib dict: the dictionary that contains the attributes 
39                             and value of the root node
40         '''
41         # Initialize the filePath and ensure that the directory 
42         # that contain the file exists (make it if necessary)
43         self.logFile = filePath
44         src.ensure_path_exists(os.path.dirname(filePath))
45         # Initialize the field that contain the xml in memory
46         self.xmlroot = etree.Element(rootname, attrib = attrib)
47     
48     def write_tree(self, stylesheet=None, file_path = None):
49         '''Write the xml tree in the log file path. Add the stylesheet if asked.
50         
51         :param stylesheet str: The stylesheet to apply to the xml file
52         '''
53         log_file_path = self.logFile
54         if file_path:
55             log_file_path = file_path
56         f = open(log_file_path, 'w')
57         f.write("<?xml version='1.0' encoding='utf-8'?>\n")
58         if stylesheet:
59             f.write("<?xml-stylesheet type='text/xsl' href='%s'?>\n" % 
60                     stylesheet)    
61         f.write(etree.tostring(self.xmlroot, encoding='utf-8'))
62         f.close()  
63         
64     def add_simple_node(self, node_name, text=None, attrib={}):
65         '''Add a node with some attibutes and text to the root node.
66         
67         :param node_name str: the name of the node to add
68         :param text str: the text of the node
69         :param attrib dict: the dictionary containing the 
70                             attribute of the new node
71         '''
72         n = etree.Element(node_name, attrib=attrib)
73         n.text = text
74         self.xmlroot.append(n)
75         return n
76     
77     def append_node_text(self, node_name, text):
78         '''Append a new text to the node that has node_name as name
79         
80         :param node_name str: The name of the node on which append text
81         :param text str: The text to append
82         '''
83         # find the corresponding node
84         for field in self.xmlroot:
85             if field.tag == node_name:
86                 # append the text
87                 field.text += text
88
89     def append_node_attrib(self, node_name, attrib):
90         '''Append a new attributes to the node that has node_name as name
91         
92         :param node_name str: The name of the node on which append text
93         :param attrib dixt: The attrib to append
94         '''
95         self.xmlroot.find(node_name).attrib.update(attrib)
96
97 class ReadXmlFile(object):
98     '''Class to manage reading of an xml log file
99     '''
100     def __init__(self, filePath):
101         '''Initialization
102         
103         :param filePath str: The xml file to be read
104         '''
105         self.filePath = filePath
106         etree_inst = etree.parse(filePath)
107         self.xmlroot = etree_inst.parse(filePath)
108
109     def getRootAttrib(self):
110         '''Get the attibutes of the self.xmlroot
111         
112         :return: The attributes of the root node
113         :rtype: dict
114         '''
115         return self.xmlroot.attrib
116     
117     def get_attrib(self, node_name):
118         '''Get the attibutes of the node node_name in self.xmlroot
119         
120         :param node_name str: the name of the node
121         :return: the attibutes of the node node_name in self.xmlroot
122         :rtype: dict
123         '''
124         attrib = self.xmlroot.find(node_name).attrib
125         # To be python 3 compatible, convert bytes to str if there are any
126         fixedAttrib = {}
127         for k in attrib.keys():
128             if isinstance(k, bytes):
129                 key = k.decode()
130             else:
131                 key = k
132             if isinstance(attrib[k], bytes):
133                 value = attrib[k].decode()
134             else:
135                 value = attrib[k]
136             fixedAttrib[key] = value
137         return fixedAttrib
138     
139     def get_node_text(self, node):
140         '''Get the text of the first node that has name 
141            that corresponds to the parameter node
142         
143         :param node str: the name of the node from which get the text
144         :return: the text of the first node that has name 
145                  that corresponds to the parameter node
146         :rtype: str
147         '''
148         return self.xmlroot.find(node).text
149     
150 def add_simple_node(root_node, node_name, text=None, attrib={}):
151     '''Add a node with some attibutes and text to the root node.
152
153     :param root_node etree.Element: the Etree element where to add the new node    
154     :param node_name str: the name of the node to add
155     :param text str: the text of the node
156     :param attrib dict: the dictionary containing the 
157                         attribute of the new node
158     '''
159     n = etree.Element(node_name, attrib=attrib)
160     n.text = text
161     root_node.append(n)
162     return n
163
164 def append_node_attrib(root_node, attrib):
165     '''Append a new attributes to the node that has node_name as name
166     
167     :param root_node etree.Element: the Etree element 
168                                     where to append the new attibutes
169     :param attrib dixt: The attrib to append
170     '''
171     root_node.attrib.update(attrib)
172
173 def find_node_by_attrib(xmlroot, name_node, key, value):
174     '''Find the nfirst ode from xmlroot that has name name_node and that has in 
175        its attributes {key : value}. Return the node
176     
177     :param xmlroot etree.Element: the Etree element where to search
178     :param name_node str: the name of node to search
179     :param key str: the key to search
180     :param value str: the value to search
181     :return: the found node
182     :rtype: xmlroot etree.Element
183     '''
184     l_nodes =  xmlroot.findall(name_node)
185     for node in l_nodes:
186         if key not in node.attrib.keys():
187             continue
188         if node.attrib[key] == value:
189             return node
190     return None
191     
192
193 def write_report(filename, xmlroot, stylesheet):
194     """Writes a report file from a XML tree.
195     
196     :param filename str: The path to the file to create
197     :param xmlroot etree.Element: the Etree element to write to the file
198     :param stylesheet str: The stylesheet to add to the begin of the file
199     """
200     if not os.path.exists(os.path.dirname(filename)):
201         os.makedirs(os.path.dirname(filename))
202
203     f = open(filename, "w")
204     f.write("<?xml version='1.0' encoding='utf-8'?>\n")
205     if len(stylesheet) > 0:
206         f.write("<?xml-stylesheet type='text/xsl' href='%s'?>\n" % stylesheet)
207     f.write(etree.tostring(xmlroot, encoding='utf-8'))
208     f.close()   
209