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