]> git.proxmox.com Git - mirror_edk2.git/blame - Tools/Python/XmlRoutines.py
Changing XmlAppendChildElement to return the new XML node on success.
[mirror_edk2.git] / Tools / Python / XmlRoutines.py
CommitLineData
77afa5eb 1#!/usr/bin/env python
2
3b7a53b6 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
13standard python so that no extra python packages are required to use it."""
77afa5eb 14
15import xml.dom.minidom
16
17def XmlList(Dom, String):
18 """Get a list of XML Elements using XPath style syntax."""
4040421a 19 if String == "" :
20 return []
77afa5eb 21 if Dom.nodeType==Dom.DOCUMENT_NODE:
22 return XmlList(Dom.documentElement, String)
23 if String[0] == "/":
24 return XmlList(Dom, String[1:])
77afa5eb 25 TagList = String.split('/')
26 nodes = []
27 if Dom.nodeType == Dom.ELEMENT_NODE and Dom.tagName.strip() == TagList[0]:
28 if len(TagList) == 1:
29 nodes = [Dom]
30 else:
31 restOfPath = "/".join(TagList[1:])
32 for child in Dom.childNodes:
33 nodes = nodes + XmlList(child, restOfPath)
34 return nodes
35
4040421a 36def XmlNode (Dom, String):
37 """Return a single node that matches the String which is XPath style syntax."""
38 try:
39 return XmlList (Dom, String)[0]
40 except:
41 return None
42
43
77afa5eb 44def XmlElement (Dom, String):
45 """Return a single element that matches the String which is XPath style syntax."""
46 try:
8d4243f1 47 return XmlList (Dom, String)[0].firstChild.data.strip()
77afa5eb 48 except:
49 return ''
50
51def XmlElementData (Dom):
52 """Get the text for this element."""
8d4243f1 53 return Dom.firstChild.data.strip()
77afa5eb 54
3b7a53b6 55def XmlAttribute (Dom, AttName):
56 """Return a single attribute named AttName."""
77afa5eb 57 try:
3b7a53b6 58 return Dom.getAttribute(AttName)
77afa5eb 59 except:
60 return ''
61
e853a9d4 62def XmlTopTag(Dom):
63 """Return the name of the Root or top tag in the XML tree."""
8d4243f1 64 return Dom.firstChild.nodeName
65
66def XmlParseFile (FileName):
67 """Parse an XML file into a DOM and return the DOM."""
68 try:
69 f = open(FileName, 'r')
70 Dom = xml.dom.minidom.parse(f)
71 f.close()
72 return Dom
73 except:
74 return xml.dom.minidom.parseString('<empty/>')
75
24a86f9a 76def XmlParseString (Str):
77 """Parse an XML string into a DOM and return the DOM."""
78 try:
79 return xml.dom.minidom.parseString(Str)
80 except:
81 return xml.dom.minidom.parseString('<empty/>')
82
8d4243f1 83def XmlParseFileSection (FileName, Tag):
84 """Parse a section of an XML file into a DOM(Document Object Model) and return the DOM."""
85 try:
86 f = open(FileName, 'r')
87 except:
88 return xml.dom.minidom.parseString('<empty/>')
89 Start = '<' + Tag
90 End = '</' + Tag + '>'
91 File = ''
92 while File.find(Start) < 0 or File.find(End) < 0:
93 Section = f.read(0x1000)
94 if Section == '':
95 break
96 File += Section
97 f.close()
98 if File.find(Start) < 0 or File.find(End) < 0:
99 return xml.dom.minidom.parseString('<empty/>')
100 File = File[File.find(Start):File.find(End)+len(End)]
101 try:
102 return xml.dom.minidom.parseString(File)
103 except:
104 return xml.dom.minidom.parseString('<empty/>')
105
4040421a 106def XmlParseStringSection (XmlString, Tag):
107 """Parse a section of an XML string into a DOM(Document Object Model) and return the DOM."""
108 Start = '<' + Tag
109 End = '</' + Tag + '>'
110 File = XmlString
111 if File.find(Start) < 0 or File.find(End) < 0:
112 return xml.dom.minidom.parseString('<empty/>')
113 File = File[File.find(Start):File.find(End)+len(End)]
114 try:
115 return xml.dom.minidom.parseString(File)
116 except:
117 return xml.dom.minidom.parseString('<empty/>')
118
8d4243f1 119def XmlSaveFile (Dom, FileName, Encoding='UTF-8'):
120 """Save a DOM(Document Object Model) into an XML file."""
121 try:
122 f = open(FileName, 'w')
123 f.write(Dom.toxml(Encoding).replace('&quot;','"').replace('&gt;','>'))
124 f.close()
125 return True
126 except:
127 return False
128
129def XmlRemoveElement(Node):
130 """Remove an element node from DOM(Document Object Model) tree."""
131 ParentNode = Node.parentNode
132 if ParentNode == None:
133 return False
134 PreviousSibling = Node.previousSibling
135 while PreviousSibling != None and PreviousSibling.nodeType == PreviousSibling.TEXT_NODE and PreviousSibling.data.strip() == '':
136 Temp = PreviousSibling
137 PreviousSibling = PreviousSibling.previousSibling
138 ParentNode.removeChild(Temp)
139 ParentNode.removeChild(Node)
140 return True
141
142def XmlAppendChildElement(ParentNode, TagName, ElementText='', AttributeDictionary = {}):
143 """Add a child element to a DOM(Document Object Model) tree with optional Attributes."""
144 TagName = TagName.strip()
145 if TagName == '':
f0a3fde1 146 return None
8d4243f1 147 Depth = 0
148 Dom = ParentNode
149 while Dom != None and Dom.nodeType != Dom.DOCUMENT_NODE:
150 Dom = Dom.parentNode
151 Depth += 1
152 if Dom == None:
f0a3fde1 153 return None
8d4243f1 154 ParentNode.appendChild(Dom.createTextNode('\n%*s' % (Depth * 2, '')))
155 ElementNode = Dom.createElement(TagName)
156 if ElementText != '':
157 ElementNode.appendChild(Dom.createTextNode(ElementText))
158 for Item in AttributeDictionary:
159 ElementNode.setAttribute(Item, AttributeDictionary[Item])
160 ParentNode.appendChild(ElementNode)
f0a3fde1 161 return ElementNode
e853a9d4 162
163
77afa5eb 164# This acts like the main() function for the script, unless it is 'import'ed into another
165# script.
166if __name__ == '__main__':
167
168 # Nothing to do here. Could do some unit tests.
169 pass