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