1 #!/usr/bin/env python 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 3 # Use of this source code is governed by a BSD-style license that can be 4 # found in the LICENSE file. 5 6 7 from grit.format.policy_templates.writers import template_writer 8 9 10 class XMLFormattedWriter(template_writer.TemplateWriter): 11 '''Helper class for generating XML-based templates. 12 ''' 13 14 def AddElement(self, parent, name, attrs=None, text=None): 15 ''' 16 Adds a new XML Element as a child to an existing element or the Document. 17 18 Args: 19 parent: An XML element or the document, where the new element will be 20 added. 21 name: The name of the new element. 22 attrs: A dictionary of the attributes' names and values for the new 23 element. 24 text: Text content for the new element. 25 26 Returns: 27 The created new element. 28 ''' 29 if attrs == None: 30 attrs = {} 31 32 doc = parent.ownerDocument 33 element = doc.createElement(name) 34 for key, value in attrs.iteritems(): 35 element.setAttribute(key, value) 36 if text: 37 element.appendChild(doc.createTextNode(text)) 38 parent.appendChild(element) 39 return element 40 41 def AddText(self, parent, text): 42 '''Adds text to a parent node. 43 ''' 44 doc = parent.ownerDocument 45 parent.appendChild(doc.createTextNode(text)) 46 47 def AddAttribute(self, parent, name, value): 48 '''Adds a new attribute to the parent Element. If an attribute with the 49 given name already exists then it will be replaced. 50 ''' 51 doc = parent.ownerDocument 52 attribute = doc.createAttribute(name) 53 attribute.value = value 54 parent.setAttributeNode(attribute) 55 56 def ToPrettyXml(self, doc): 57 # return doc.toprettyxml(indent=' ') 58 # The above pretty-printer does not print the doctype and adds spaces 59 # around texts, e.g.: 60 # <string> 61 # value of the string 62 # </string> 63 # This is problematic both for the OSX Workgroup Manager (plist files) and 64 # the Windows Group Policy Editor (admx files). What they need instead: 65 # <string>value of string</string> 66 # So we use the poor man's pretty printer here. It assumes that there are 67 # no mixed-content nodes. 68 # Get all the XML content in a one-line string. 69 xml = doc.toxml() 70 # Determine where the line breaks will be. (They will only be between tags.) 71 lines = xml[1:len(xml) - 1].split('><') 72 indent = '' 73 res = '' 74 # Determine indent for each line. 75 for i, line in enumerate(lines): 76 if line[0] == '/': 77 # If the current line starts with a closing tag, decrease indent before 78 # printing. 79 indent = indent[2:] 80 lines[i] = indent + '<' + line + '>' 81 if (line[0] not in ['/', '?', '!'] and '</' not in line and 82 line[len(line) - 1] != '/'): 83 # If the current line starts with an opening tag and does not conatin a 84 # closing tag, increase indent after the line is printed. 85 indent += ' ' 86 # Reconstruct XML text from the lines. 87 return '\n'.join(lines) 88