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