Python script for generating build files for platform and modules, which uses the...
[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
76def XmlParseFileSection (FileName, Tag):
77 """Parse a section of an XML file into a DOM(Document Object Model) and return the DOM."""
78 try:
79 f = open(FileName, 'r')
80 except:
81 return xml.dom.minidom.parseString('<empty/>')
82 Start = '<' + Tag
83 End = '</' + Tag + '>'
84 File = ''
85 while File.find(Start) < 0 or File.find(End) < 0:
86 Section = f.read(0x1000)
87 if Section == '':
88 break
89 File += Section
90 f.close()
91 if File.find(Start) < 0 or File.find(End) < 0:
92 return xml.dom.minidom.parseString('<empty/>')
93 File = File[File.find(Start):File.find(End)+len(End)]
94 try:
95 return xml.dom.minidom.parseString(File)
96 except:
97 return xml.dom.minidom.parseString('<empty/>')
98
4040421a 99def XmlParseStringSection (XmlString, Tag):
100 """Parse a section of an XML string into a DOM(Document Object Model) and return the DOM."""
101 Start = '<' + Tag
102 End = '</' + Tag + '>'
103 File = XmlString
104 if File.find(Start) < 0 or File.find(End) < 0:
105 return xml.dom.minidom.parseString('<empty/>')
106 File = File[File.find(Start):File.find(End)+len(End)]
107 try:
108 return xml.dom.minidom.parseString(File)
109 except:
110 return xml.dom.minidom.parseString('<empty/>')
111
8d4243f1 112def XmlSaveFile (Dom, FileName, Encoding='UTF-8'):
113 """Save a DOM(Document Object Model) into an XML file."""
114 try:
115 f = open(FileName, 'w')
116 f.write(Dom.toxml(Encoding).replace('&quot;','"').replace('&gt;','>'))
117 f.close()
118 return True
119 except:
120 return False
121
122def XmlRemoveElement(Node):
123 """Remove an element node from DOM(Document Object Model) tree."""
124 ParentNode = Node.parentNode
125 if ParentNode == None:
126 return False
127 PreviousSibling = Node.previousSibling
128 while PreviousSibling != None and PreviousSibling.nodeType == PreviousSibling.TEXT_NODE and PreviousSibling.data.strip() == '':
129 Temp = PreviousSibling
130 PreviousSibling = PreviousSibling.previousSibling
131 ParentNode.removeChild(Temp)
132 ParentNode.removeChild(Node)
133 return True
134
135def XmlAppendChildElement(ParentNode, TagName, ElementText='', AttributeDictionary = {}):
136 """Add a child element to a DOM(Document Object Model) tree with optional Attributes."""
137 TagName = TagName.strip()
138 if TagName == '':
139 return False
140 Depth = 0
141 Dom = ParentNode
142 while Dom != None and Dom.nodeType != Dom.DOCUMENT_NODE:
143 Dom = Dom.parentNode
144 Depth += 1
145 if Dom == None:
146 return False
147 ParentNode.appendChild(Dom.createTextNode('\n%*s' % (Depth * 2, '')))
148 ElementNode = Dom.createElement(TagName)
149 if ElementText != '':
150 ElementNode.appendChild(Dom.createTextNode(ElementText))
151 for Item in AttributeDictionary:
152 ElementNode.setAttribute(Item, AttributeDictionary[Item])
153 ParentNode.appendChild(ElementNode)
154 return True
e853a9d4 155
156
77afa5eb 157# This acts like the main() function for the script, unless it is 'import'ed into another
158# script.
159if __name__ == '__main__':
160
161 # Nothing to do here. Could do some unit tests.
162 pass