Home | History | Annotate | Download | only in Xml
      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