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) 2011 - 2014, Intel Corporation. All rights reserved.<BR> 6 # 7 # This program and the accompanying materials are licensed and made available 8 # under the terms and conditions of the BSD License which accompanies this 9 # distribution. The full text of the license may be found at 10 # http://opensource.org/licenses/bsd-license.php 11 # 12 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 13 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 14 # 15 16 ''' 17 XmlRoutines 18 ''' 19 20 ## 21 # Import Modules 22 # 23 import xml.dom.minidom 24 import re 25 import codecs 26 from Logger.ToolError import PARSER_ERROR 27 import Logger.Log as Logger 28 29 ## Create a element of XML 30 # 31 # @param Name 32 # @param String 33 # @param NodeList 34 # @param AttributeList 35 # 36 def CreateXmlElement(Name, String, NodeList, AttributeList): 37 Doc = xml.dom.minidom.Document() 38 Element = Doc.createElement(Name) 39 if String != '' and String != None: 40 Element.appendChild(Doc.createTextNode(String)) 41 42 for Item in NodeList: 43 if type(Item) == type([]): 44 Key = Item[0] 45 Value = Item[1] 46 if Key != '' and Key != None and Value != '' and Value != None: 47 Node = Doc.createElement(Key) 48 Node.appendChild(Doc.createTextNode(Value)) 49 Element.appendChild(Node) 50 else: 51 Element.appendChild(Item) 52 for Item in AttributeList: 53 Key = Item[0] 54 Value = Item[1] 55 if Key != '' and Key != None and Value != '' and Value != None: 56 Element.setAttribute(Key, Value) 57 58 return Element 59 60 ## Get a list of XML nodes using XPath style syntax. 61 # 62 # Return a list of XML DOM nodes from the root Dom specified by XPath String. 63 # If the input Dom or String is not valid, then an empty list is returned. 64 # 65 # @param Dom The root XML DOM node. 66 # @param String A XPath style path. 67 # 68 def XmlList(Dom, String): 69 if String == None or String == "" or Dom == None or Dom == "": 70 return [] 71 if Dom.nodeType == Dom.DOCUMENT_NODE: 72 Dom = Dom.documentElement 73 if String[0] == "/": 74 String = String[1:] 75 TagList = String.split('/') 76 Nodes = [Dom] 77 Index = 0 78 End = len(TagList) - 1 79 while Index <= End: 80 ChildNodes = [] 81 for Node in Nodes: 82 if Node.nodeType == Node.ELEMENT_NODE and Node.tagName == \ 83 TagList[Index]: 84 if Index < End: 85 ChildNodes.extend(Node.childNodes) 86 else: 87 ChildNodes.append(Node) 88 Nodes = ChildNodes 89 ChildNodes = [] 90 Index += 1 91 92 return Nodes 93 94 95 ## Get a single XML node using XPath style syntax. 96 # 97 # Return a single XML DOM node from the root Dom specified by XPath String. 98 # If the input Dom or String is not valid, then an empty string is returned. 99 # 100 # @param Dom The root XML DOM node. 101 # @param String A XPath style path. 102 # 103 def XmlNode(Dom, String): 104 if String == None or String == "" or Dom == None or Dom == "": 105 return None 106 if Dom.nodeType == Dom.DOCUMENT_NODE: 107 Dom = Dom.documentElement 108 if String[0] == "/": 109 String = String[1:] 110 TagList = String.split('/') 111 Index = 0 112 End = len(TagList) - 1 113 ChildNodes = [Dom] 114 while Index <= End: 115 for Node in ChildNodes: 116 if Node.nodeType == Node.ELEMENT_NODE and \ 117 Node.tagName == TagList[Index]: 118 if Index < End: 119 ChildNodes = Node.childNodes 120 else: 121 return Node 122 break 123 Index += 1 124 return None 125 126 127 ## Get a single XML element using XPath style syntax. 128 # 129 # Return a single XML element from the root Dom specified by XPath String. 130 # If the input Dom or String is not valid, then an empty string is returned. 131 # 132 # @param Dom The root XML DOM object. 133 # @param Strin A XPath style path. 134 # 135 def XmlElement(Dom, String): 136 try: 137 return XmlNode(Dom, String).firstChild.data.strip() 138 except BaseException: 139 return "" 140 141 ## Get a single XML element using XPath style syntax. 142 # 143 # Similar with XmlElement, but do not strip all the leading and tailing space 144 # and newline, instead just remove the newline and spaces introduced by 145 # toprettyxml() 146 # 147 # @param Dom The root XML DOM object. 148 # @param Strin A XPath style path. 149 # 150 def XmlElement2(Dom, String): 151 try: 152 HelpStr = XmlNode(Dom, String).firstChild.data 153 gRemovePrettyRe = re.compile(r"""(?:(\n *) )(.*)\1""", re.DOTALL) 154 HelpStr = re.sub(gRemovePrettyRe, r"\2", HelpStr) 155 return HelpStr 156 except BaseException: 157 return "" 158 159 160 ## Get a single XML element of the current node. 161 # 162 # Return a single XML element specified by the current root Dom. 163 # If the input Dom is not valid, then an empty string is returned. 164 # 165 # @param Dom The root XML DOM object. 166 # 167 def XmlElementData(Dom): 168 try: 169 return Dom.firstChild.data.strip() 170 except BaseException: 171 return "" 172 173 174 ## Get a list of XML elements using XPath style syntax. 175 # 176 # Return a list of XML elements from the root Dom specified by XPath String. 177 # If the input Dom or String is not valid, then an empty list is returned. 178 # 179 # @param Dom The root XML DOM object. 180 # @param String A XPath style path. 181 # 182 def XmlElementList(Dom, String): 183 return map(XmlElementData, XmlList(Dom, String)) 184 185 186 ## Get the XML attribute of the current node. 187 # 188 # Return a single XML attribute named Attribute from the current root Dom. 189 # If the input Dom or Attribute is not valid, then an empty string is returned. 190 # 191 # @param Dom The root XML DOM object. 192 # @param Attribute The name of Attribute. 193 # 194 def XmlAttribute(Dom, Attribute): 195 try: 196 return Dom.getAttribute(Attribute) 197 except BaseException: 198 return '' 199 200 201 ## Get the XML node name of the current node. 202 # 203 # Return a single XML node name from the current root Dom. 204 # If the input Dom is not valid, then an empty string is returned. 205 # 206 # @param Dom The root XML DOM object. 207 # 208 def XmlNodeName(Dom): 209 try: 210 return Dom.nodeName.strip() 211 except BaseException: 212 return '' 213 214 ## Parse an XML file. 215 # 216 # Parse the input XML file named FileName and return a XML DOM it stands for. 217 # If the input File is not a valid XML file, then an empty string is returned. 218 # 219 # @param FileName The XML file name. 220 # 221 def XmlParseFile(FileName): 222 try: 223 XmlFile = codecs.open(FileName, 'rb') 224 Dom = xml.dom.minidom.parse(XmlFile) 225 XmlFile.close() 226 return Dom 227 except BaseException, XExcept: 228 XmlFile.close() 229 Logger.Error('\nUPT', PARSER_ERROR, XExcept, File=FileName, RaiseError=True) 230