]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/UPT/Library/Xml/XmlRoutines.py
BaseTools: Fix old python2 idioms
[mirror_edk2.git] / BaseTools / Source / Python / UPT / Library / Xml / XmlRoutines.py
1 ## @file
2 # This is an XML API that uses a syntax similar to XPath, but it is written in
3 # standard python so that no extra python packages are required to use it.
4 #
5 # Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR>
6 #
7 # This program and the accompanying materials are licensed and made available
8 # under the terms and conditions of the BSD License which accompanies this
9 # distribution. The full text of the license may be found at
10 # http://opensource.org/licenses/bsd-license.php
11 #
12 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14 #
15
16 '''
17 XmlRoutines
18 '''
19
20 ##
21 # Import Modules
22 #
23 import xml.dom.minidom
24 import re
25 import codecs
26 from Logger.ToolError import PARSER_ERROR
27 import Logger.Log as Logger
28
29 ## Create a element of XML
30 #
31 # @param Name
32 # @param String
33 # @param NodeList
34 # @param AttributeList
35 #
36 def CreateXmlElement(Name, String, NodeList, AttributeList):
37 Doc = xml.dom.minidom.Document()
38 Element = Doc.createElement(Name)
39 if String != '' and String is not None:
40 Element.appendChild(Doc.createTextNode(String))
41
42 for Item in NodeList:
43 if isinstance(Item, type([])):
44 Key = Item[0]
45 Value = Item[1]
46 if Key != '' and Key is not None and Value != '' and Value is not None:
47 Node = Doc.createElement(Key)
48 Node.appendChild(Doc.createTextNode(Value))
49 Element.appendChild(Node)
50 else:
51 Element.appendChild(Item)
52 for Item in AttributeList:
53 Key = Item[0]
54 Value = Item[1]
55 if Key != '' and Key is not None and Value != '' and Value is not None:
56 Element.setAttribute(Key, Value)
57
58 return Element
59
60 ## Get a list of XML nodes using XPath style syntax.
61 #
62 # Return a list of XML DOM nodes from the root Dom specified by XPath String.
63 # If the input Dom or String is not valid, then an empty list is returned.
64 #
65 # @param Dom The root XML DOM node.
66 # @param String A XPath style path.
67 #
68 def XmlList(Dom, String):
69 if String is None or String == "" or Dom is None or Dom == "":
70 return []
71 if Dom.nodeType == Dom.DOCUMENT_NODE:
72 Dom = Dom.documentElement
73 if String[0] == "/":
74 String = String[1:]
75 TagList = String.split('/')
76 Nodes = [Dom]
77 Index = 0
78 End = len(TagList) - 1
79 while Index <= End:
80 ChildNodes = []
81 for Node in Nodes:
82 if Node.nodeType == Node.ELEMENT_NODE and Node.tagName == \
83 TagList[Index]:
84 if Index < End:
85 ChildNodes.extend(Node.childNodes)
86 else:
87 ChildNodes.append(Node)
88 Nodes = ChildNodes
89 ChildNodes = []
90 Index += 1
91
92 return Nodes
93
94
95 ## Get a single XML node using XPath style syntax.
96 #
97 # Return a single XML DOM node from the root Dom specified by XPath String.
98 # If the input Dom or String is not valid, then an empty string is returned.
99 #
100 # @param Dom The root XML DOM node.
101 # @param String A XPath style path.
102 #
103 def XmlNode(Dom, String):
104 if String is None or String == "" or Dom is None or Dom == "":
105 return None
106 if Dom.nodeType == Dom.DOCUMENT_NODE:
107 Dom = Dom.documentElement
108 if String[0] == "/":
109 String = String[1:]
110 TagList = String.split('/')
111 Index = 0
112 End = len(TagList) - 1
113 ChildNodes = [Dom]
114 while Index <= End:
115 for Node in ChildNodes:
116 if Node.nodeType == Node.ELEMENT_NODE and \
117 Node.tagName == TagList[Index]:
118 if Index < End:
119 ChildNodes = Node.childNodes
120 else:
121 return Node
122 break
123 Index += 1
124 return None
125
126
127 ## Get a single XML element using XPath style syntax.
128 #
129 # Return a single XML element from the root Dom specified by XPath String.
130 # If the input Dom or String is not valid, then an empty string is returned.
131 #
132 # @param Dom The root XML DOM object.
133 # @param Strin A XPath style path.
134 #
135 def XmlElement(Dom, String):
136 try:
137 return XmlNode(Dom, String).firstChild.data.strip()
138 except BaseException:
139 return ""
140
141 ## Get a single XML element using XPath style syntax.
142 #
143 # Similar with XmlElement, but do not strip all the leading and tailing space
144 # and newline, instead just remove the newline and spaces introduced by
145 # toprettyxml()
146 #
147 # @param Dom The root XML DOM object.
148 # @param Strin A XPath style path.
149 #
150 def XmlElement2(Dom, String):
151 try:
152 HelpStr = XmlNode(Dom, String).firstChild.data
153 gRemovePrettyRe = re.compile(r"""(?:(\n *) )(.*)\1""", re.DOTALL)
154 HelpStr = re.sub(gRemovePrettyRe, r"\2", HelpStr)
155 return HelpStr
156 except BaseException:
157 return ""
158
159
160 ## Get a single XML element of the current node.
161 #
162 # Return a single XML element specified by the current root Dom.
163 # If the input Dom is not valid, then an empty string is returned.
164 #
165 # @param Dom The root XML DOM object.
166 #
167 def XmlElementData(Dom):
168 try:
169 return Dom.firstChild.data.strip()
170 except BaseException:
171 return ""
172
173
174 ## Get a list of XML elements using XPath style syntax.
175 #
176 # Return a list of XML elements from the root Dom specified by XPath String.
177 # If the input Dom or String is not valid, then an empty list is returned.
178 #
179 # @param Dom The root XML DOM object.
180 # @param String A XPath style path.
181 #
182 def XmlElementList(Dom, String):
183 return map(XmlElementData, XmlList(Dom, String))
184
185
186 ## Get the XML attribute of the current node.
187 #
188 # Return a single XML attribute named Attribute from the current root Dom.
189 # If the input Dom or Attribute is not valid, then an empty string is returned.
190 #
191 # @param Dom The root XML DOM object.
192 # @param Attribute The name of Attribute.
193 #
194 def XmlAttribute(Dom, Attribute):
195 try:
196 return Dom.getAttribute(Attribute)
197 except BaseException:
198 return ''
199
200
201 ## Get the XML node name of the current node.
202 #
203 # Return a single XML node name from the current root Dom.
204 # If the input Dom is not valid, then an empty string is returned.
205 #
206 # @param Dom The root XML DOM object.
207 #
208 def XmlNodeName(Dom):
209 try:
210 return Dom.nodeName.strip()
211 except BaseException:
212 return ''
213
214 ## Parse an XML file.
215 #
216 # Parse the input XML file named FileName and return a XML DOM it stands for.
217 # If the input File is not a valid XML file, then an empty string is returned.
218 #
219 # @param FileName The XML file name.
220 #
221 def XmlParseFile(FileName):
222 try:
223 XmlFile = codecs.open(FileName, 'rb')
224 Dom = xml.dom.minidom.parse(XmlFile)
225 XmlFile.close()
226 return Dom
227 except BaseException as XExcept:
228 XmlFile.close()
229 Logger.Error('\nUPT', PARSER_ERROR, XExcept, File=FileName, RaiseError=True)