Import BaseMemoryLibMmx;
[mirror_edk2.git] / Tools / Python / XmlRoutines.py
1 #!/usr/bin/env python
2
3 # Copyright (c) 2007, Intel Corporation
4 # All rights reserved. This program and the accompanying materials
5 # are licensed and made available under the terms and conditions of the BSD License
6 # which accompanies this distribution. The full text of the license may be found at
7 # http://opensource.org/licenses/bsd-license.php
8 #
9 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 """This is an XML API that uses a syntax similar to XPath, but it is written in
13 standard python so that no extra python packages are required to use it."""
14
15 import xml.dom.minidom
16
17 def XmlList(Dom, String):
18 """Get a list of XML Elements using XPath style syntax."""
19 if String == None or String == "" or Dom == None or Dom == "":
20 return []
21 if Dom.nodeType==Dom.DOCUMENT_NODE:
22 Dom = Dom.documentElement
23 if String[0] == "/":
24 String = String[1:]
25 tagList = String.split('/')
26 nodes = [Dom]
27 index = 0
28 end = len(tagList) - 1
29 while index <= end:
30 childNodes = []
31 for node in nodes:
32 if node.nodeType == node.ELEMENT_NODE and node.tagName == tagList[index]:
33 if index < end:
34 childNodes.extend(node.childNodes)
35 else:
36 childNodes.append(node)
37 nodes = childNodes
38 childNodes = []
39 index += 1
40
41 return nodes
42
43 def XmlNode (Dom, String):
44 """Return a single node that matches the String which is XPath style syntax."""
45 if String == None or String == "" or Dom == None or Dom == "":
46 return ""
47 if Dom.nodeType==Dom.DOCUMENT_NODE:
48 Dom = Dom.documentElement
49 if String[0] == "/":
50 String = String[1:]
51 tagList = String.split('/')
52 index = 0
53 end = len(tagList) - 1
54 childNodes = [Dom]
55 while index <= end:
56 for node in childNodes:
57 if node.nodeType == node.ELEMENT_NODE and node.tagName == tagList[index]:
58 if index < end:
59 childNodes = node.childNodes
60 else:
61 return node
62 break
63 index += 1
64 return ""
65
66 def XmlElement (Dom, String):
67 """Return a single element that matches the String which is XPath style syntax."""
68 try:
69 return XmlNode (Dom, String).firstChild.data.strip()
70 except:
71 return ''
72
73 def XmlElementData (Dom):
74 """Get the text for this element."""
75 if Dom == None or Dom == '' or Dom.firstChild == None:
76 return ''
77 return Dom.firstChild.data.strip()
78
79 def XmlAttribute (Dom, AttName):
80 """Return a single attribute named AttName."""
81 if Dom == None or Dom == '':
82 return ''
83 try:
84 return Dom.getAttribute(AttName)
85 except:
86 return ''
87
88 def XmlTopTag(Dom):
89 """Return the name of the Root or top tag in the XML tree."""
90 return Dom.firstChild.nodeName
91
92 def XmlParseFile (FileName):
93 """Parse an XML file into a DOM and return the DOM."""
94 try:
95 f = open(FileName, 'r')
96 Dom = xml.dom.minidom.parse(f)
97 f.close()
98 return Dom
99 except:
100 return xml.dom.minidom.parseString('<empty/>')
101
102 def XmlParseString (Str):
103 """Parse an XML string into a DOM and return the DOM."""
104 try:
105 return xml.dom.minidom.parseString(Str)
106 except:
107 return xml.dom.minidom.parseString('<empty/>')
108
109 def XmlParseFileSection (FileName, Tag):
110 """Parse a section of an XML file into a DOM(Document Object Model) and return the DOM."""
111 try:
112 f = open(FileName, 'r')
113 except:
114 return xml.dom.minidom.parseString('<empty/>')
115 Start = '<' + Tag
116 End = '</' + Tag + '>'
117 File = ''
118 while File.find(Start) < 0 or File.find(End) < 0:
119 Section = f.read(0x1000)
120 if Section == '':
121 break
122 File += Section
123 f.close()
124 if File.find(Start) < 0 or File.find(End) < 0:
125 return xml.dom.minidom.parseString('<empty/>')
126 File = File[File.find(Start):File.find(End)+len(End)]
127 try:
128 return xml.dom.minidom.parseString(File)
129 except:
130 return xml.dom.minidom.parseString('<empty/>')
131
132 def XmlParseStringSection (XmlString, Tag):
133 """Parse a section of an XML string into a DOM(Document Object Model) and return the DOM."""
134 Start = '<' + Tag
135 End = '</' + Tag + '>'
136 File = XmlString
137 if File.find(Start) < 0 or File.find(End) < 0:
138 return xml.dom.minidom.parseString('<empty/>')
139 File = File[File.find(Start):File.find(End)+len(End)]
140 try:
141 return xml.dom.minidom.parseString(File)
142 except:
143 return xml.dom.minidom.parseString('<empty/>')
144
145 def XmlSaveFile (Dom, FileName, Encoding='UTF-8'):
146 """Save a DOM(Document Object Model) into an XML file."""
147 try:
148 f = open(FileName, 'w')
149 f.write(Dom.toxml(Encoding).replace('&quot;','"').replace('&gt;','>'))
150 f.close()
151 return True
152 except:
153 return False
154
155 def XmlRemoveElement(Node):
156 """Remove an element node from DOM(Document Object Model) tree."""
157 ParentNode = Node.parentNode
158 if ParentNode == None:
159 return False
160 PreviousSibling = Node.previousSibling
161 while PreviousSibling != None and PreviousSibling.nodeType == PreviousSibling.TEXT_NODE and PreviousSibling.data.strip() == '':
162 Temp = PreviousSibling
163 PreviousSibling = PreviousSibling.previousSibling
164 ParentNode.removeChild(Temp)
165 ParentNode.removeChild(Node)
166 return True
167
168 def XmlAppendChildElement(ParentNode, TagName, ElementText='', AttributeDictionary = {}):
169 """Add a child element to a DOM(Document Object Model) tree with optional Attributes."""
170 TagName = TagName.strip()
171 if TagName == '':
172 return None
173 Depth = 0
174 Dom = ParentNode
175 while Dom != None and Dom.nodeType != Dom.DOCUMENT_NODE:
176 Dom = Dom.parentNode
177 Depth += 1
178 if Dom == None:
179 return None
180 ParentNode.appendChild(Dom.createTextNode('\n%*s' % (Depth * 2, '')))
181 ElementNode = Dom.createElement(TagName)
182 if ElementText != '':
183 ElementNode.appendChild(Dom.createTextNode(ElementText))
184 for Item in AttributeDictionary:
185 ElementNode.setAttribute(Item, AttributeDictionary[Item])
186 ParentNode.appendChild(ElementNode)
187 return ElementNode
188
189
190 # This acts like the main() function for the script, unless it is 'import'ed into another
191 # script.
192 if __name__ == '__main__':
193
194 # Nothing to do here. Could do some unit tests.
195 pass