]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/Ecc/Xml/XmlRoutines.py
BaseTools: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / BaseTools / Source / Python / Ecc / 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) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
6 # SPDX-License-Identifier: BSD-2-Clause-Patent
7 #
8
9 ##
10 # Import Modules
11 #
12 from __future__ import print_function
13 import xml.dom.minidom
14 import codecs
15 from Common.LongFilePathSupport import OpenLongFilePath as open
16
17 ## Create a element of XML
18 #
19 # @param Name
20 # @param String
21 # @param NodeList
22 # @param AttributeList
23 #
24 # @revel Element
25 #
26 def CreateXmlElement(Name, String, NodeList, AttributeList):
27 Doc = xml.dom.minidom.Document()
28 Element = Doc.createElement(Name)
29 if String != '' and String is not None:
30 Element.appendChild(Doc.createTextNode(String))
31
32 for Item in NodeList:
33 if isinstance(Item, type([])):
34 Key = Item[0]
35 Value = Item[1]
36 if Key != '' and Key is not None and Value != '' and Value is not None:
37 Node = Doc.createElement(Key)
38 Node.appendChild(Doc.createTextNode(Value))
39 Element.appendChild(Node)
40 else:
41 Element.appendChild(Item)
42 for Item in AttributeList:
43 Key = Item[0]
44 Value = Item[1]
45 if Key != '' and Key is not None and Value != '' and Value is not None:
46 Element.setAttribute(Key, Value)
47
48 return Element
49
50 ## Get a list of XML nodes using XPath style syntax.
51 #
52 # Return a list of XML DOM nodes from the root Dom specified by XPath String.
53 # If the input Dom or String is not valid, then an empty list is returned.
54 #
55 # @param Dom The root XML DOM node.
56 # @param String A XPath style path.
57 #
58 # @revel Nodes A list of XML nodes matching XPath style Sting.
59 #
60 def XmlList(Dom, String):
61 if String is None or String == "" or Dom is None or Dom == "":
62 return []
63 if Dom.nodeType == Dom.DOCUMENT_NODE:
64 Dom = Dom.documentElement
65 if String[0] == "/":
66 String = String[1:]
67 TagList = String.split('/')
68 Nodes = [Dom]
69 Index = 0
70 End = len(TagList) - 1
71 while Index <= End:
72 ChildNodes = []
73 for Node in Nodes:
74 if Node.nodeType == Node.ELEMENT_NODE and Node.tagName == TagList[Index]:
75 if Index < End:
76 ChildNodes.extend(Node.childNodes)
77 else:
78 ChildNodes.append(Node)
79 Nodes = ChildNodes
80 ChildNodes = []
81 Index += 1
82
83 return Nodes
84
85
86 ## Get a single XML node using XPath style syntax.
87 #
88 # Return a single XML DOM node from the root Dom specified by XPath String.
89 # If the input Dom or String is not valid, then an empty string is returned.
90 #
91 # @param Dom The root XML DOM node.
92 # @param String A XPath style path.
93 #
94 # @revel Node A single XML node matching XPath style Sting.
95 #
96 def XmlNode(Dom, String):
97 if String is None or String == "" or Dom is None or Dom == "":
98 return ""
99 if Dom.nodeType == Dom.DOCUMENT_NODE:
100 Dom = Dom.documentElement
101 if String[0] == "/":
102 String = String[1:]
103 TagList = String.split('/')
104 Index = 0
105 End = len(TagList) - 1
106 ChildNodes = [Dom]
107 while Index <= End:
108 for Node in ChildNodes:
109 if Node.nodeType == Node.ELEMENT_NODE and Node.tagName == TagList[Index]:
110 if Index < End:
111 ChildNodes = Node.childNodes
112 else:
113 return Node
114 break
115 Index += 1
116 return ""
117
118
119 ## Get a single XML element using XPath style syntax.
120 #
121 # Return a single XML element from the root Dom specified by XPath String.
122 # If the input Dom or String is not valid, then an empty string is returned.
123 #
124 # @param Dom The root XML DOM object.
125 # @param Strin A XPath style path.
126 #
127 # @revel Element An XML element matching XPath style Sting.
128 #
129 def XmlElement(Dom, String):
130 try:
131 return XmlNode(Dom, String).firstChild.data.strip()
132 except:
133 return ""
134
135
136 ## Get a single XML element of the current node.
137 #
138 # Return a single XML element specified by the current root Dom.
139 # If the input Dom is not valid, then an empty string is returned.
140 #
141 # @param Dom The root XML DOM object.
142 #
143 # @revel Element An XML element in current root Dom.
144 #
145 def XmlElementData(Dom):
146 try:
147 return Dom.firstChild.data.strip()
148 except:
149 return ""
150
151
152 ## Get a list of XML elements using XPath style syntax.
153 #
154 # Return a list of XML elements from the root Dom specified by XPath String.
155 # If the input Dom or String is not valid, then an empty list is returned.
156 #
157 # @param Dom The root XML DOM object.
158 # @param String A XPath style path.
159 #
160 # @revel Elements A list of XML elements matching XPath style Sting.
161 #
162 def XmlElementList(Dom, String):
163 return map(XmlElementData, XmlList(Dom, String))
164
165
166 ## Get the XML attribute of the current node.
167 #
168 # Return a single XML attribute named Attribute from the current root Dom.
169 # If the input Dom or Attribute is not valid, then an empty string is returned.
170 #
171 # @param Dom The root XML DOM object.
172 # @param Attribute The name of Attribute.
173 #
174 # @revel Element A single XML element matching XPath style Sting.
175 #
176 def XmlAttribute(Dom, Attribute):
177 try:
178 return Dom.getAttribute(Attribute).strip()
179 except:
180 return ''
181
182
183 ## Get the XML node name of the current node.
184 #
185 # Return a single XML node name from the current root Dom.
186 # If the input Dom is not valid, then an empty string is returned.
187 #
188 # @param Dom The root XML DOM object.
189 #
190 # @revel Element A single XML element matching XPath style Sting.
191 #
192 def XmlNodeName(Dom):
193 try:
194 return Dom.nodeName.strip()
195 except:
196 return ''
197
198 ## Parse an XML file.
199 #
200 # Parse the input XML file named FileName and return a XML DOM it stands for.
201 # If the input File is not a valid XML file, then an empty string is returned.
202 #
203 # @param FileName The XML file name.
204 #
205 # @revel Dom The Dom object achieved from the XML file.
206 #
207 def XmlParseFile(FileName):
208 try:
209 XmlFile = codecs.open(FileName,encoding='utf_8_sig')
210 Dom = xml.dom.minidom.parse(XmlFile)
211 XmlFile.close()
212 return Dom
213 except Exception as X:
214 print(X)
215 return ""
216
217 # This acts like the main() function for the script, unless it is 'import'ed
218 # into another script.
219 if __name__ == '__main__':
220 # Nothing to do here. Could do some unit tests.
221 A = CreateXmlElement('AAA', 'CCC', [['AAA', '111'], ['BBB', '222']], [['A', '1'], ['B', '2']])
222 B = CreateXmlElement('ZZZ', 'CCC', [['XXX', '111'], ['YYY', '222']], [['A', '1'], ['B', '2']])
223 C = CreateXmlList('DDD', 'EEE', [A, B], ['FFF', 'GGG'])
224 print(C.toprettyxml(indent = " "))
225 pass