1 import os
2 from lxml import etree
3 from StringIO import StringIO
4 from Helper import Helper
5 from HelperException import FileNotExistException, BadFormatException, NotImplementedException
6
8 """
9 Helper class to manipulate the data in Xml format
10 """
11 _schema = None
12 _tree = None
13
15 """
16 Constructor for class
17
18 @param data : the xml string to be processed (alternatively, it can the location of the xml file)
19 @param schema : path to the xml schema file
20
21 """
22 Helper.__init__(self)
23
24 self._schema = schema
25 ss = data
26 if not data.lstrip().startswith('<'):
27 if os.access(data, os.F_OK):
28 raise FileNotExistException("XML file path location [%s] does not exist or not accessible " % data[:63])
29 with open(data, 'rb') as fd:
30 ss = fd.read()
31 if not ss.lstrip().startswith('<'):
32 raise BadFormatException('Data input is not a valid XML string\n%s' % ss[:63])
33 try:
34 self._tree = etree.parse(StringIO(data))
35 except etree.XMLSyntaxError, e:
36 raise BadFormatException("XML cannot be parsed with error message:\n%s" % e.error_log.last_error)
37
38
40 """
41 Check if Xml string is compliant with schema
42
43 @param schema : path to the xml schema file
44
45 @return (bool) whether schema validation is passed
46 """
47 if schema:
48 self._schema = schema
49 ss = self._schema
50 if not self._schema.lstrip().startswith('<'):
51 if os.access(self._schema, os.F_OK):
52 raise FileNotExistException("Xml schema path location [%s] does not exist or not accessible " % self._schema)
53 with open(self._schema, 'rb') as fd:
54 ss = fd.read()
55 if not ss.lstrip().startswith('<'):
56 raise BadFormatException('Schema file content is not a valid XML string\n%s' % ss)
57 es = etree.XMLSchema(etree.parse(StringIO(ss)))
58 status = es.validate(self._tree)
59 return status, es.error_log
60
61
63 """
64 Get the root element of the xml
65
66 @return: root element
67 """
68 return self._tree.getroot()
69
70
72 """
73 Get all elements' text values using XPath
74
75 @param xpath : Xpath used to search for elements text
76
77 @return: all matching elements' text values from Xpath search result in a list
78 """
79 return map(lambda x: x.text, self._tree.xpath(xpath))
80
81
83 """
84 Get all elements using XPath
85
86 @param xpath : Xpath used to search for elements
87
88 @return : all matching elements from Xpath search result in a list
89 """
90 return self._tree.xpath(xpath)
91
92
93 - def getElementTextByXPath(self, xpath):
94 """
95 Get the first element text using XPath
96
97 @param xpath : Xpath used to search for elements text
98
99 @return : the first matching element text from Xpath search result
100 """
101 texts = self.getElementsTextByXPath(xpath)
102 return texts[0] if texts else None
103
104
106 """
107 Get the first element using XPath
108
109 @param xpath : Xpath used to search for element
110
111 @return : the first matching element from Xpath search result
112 """
113 elements = self.getElementsByXPath(xpath)
114 return elements[0] if elements else None
115
116
118 """
119 Print Xml data in a nice format
120
121 @param pretty_print : do you want to be pretty?
122
123 @return : formatted xml string
124 """
125 return etree.tostring(self._tree, pretty_print=pretty_print)
126