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