aboutsummaryrefslogtreecommitdiff
path: root/grit/format/policy_templates/writers/xml_formatted_writer.py
blob: dad3717bfdc1140b55f2d8ad56dec1e8895a4210 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#!/usr/bin/env python
# Copyright (c) 2012 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.


from grit.format.policy_templates.writers import template_writer


class XMLFormattedWriter(template_writer.TemplateWriter):
  '''Helper class for generating XML-based templates.
  '''

  def AddElement(self, parent, name, attrs=None, text=None):
    '''
    Adds a new XML Element as a child to an existing element or the Document.

    Args:
      parent: An XML element or the document, where the new element will be
        added.
      name: The name of the new element.
      attrs: A dictionary of the attributes' names and values for the new
        element.
      text: Text content for the new element.

    Returns:
      The created new element.
    '''
    if attrs == None:
      attrs = {}

    doc = parent.ownerDocument
    element = doc.createElement(name)
    for key, value in attrs.iteritems():
      element.setAttribute(key, value)
    if text:
      element.appendChild(doc.createTextNode(text))
    parent.appendChild(element)
    return element

  def AddText(self, parent, text):
    '''Adds text to a parent node.
    '''
    doc = parent.ownerDocument
    parent.appendChild(doc.createTextNode(text))

  def AddAttribute(self, parent, name, value):
    '''Adds a new attribute to the parent Element. If an attribute with the
    given name already exists then it will be replaced.
    '''
    doc = parent.ownerDocument
    attribute = doc.createAttribute(name)
    attribute.value = value
    parent.setAttributeNode(attribute)

  def AddComment(self, parent, comment):
    '''Adds a comment node.'''
    parent.appendChild(parent.ownerDocument.createComment(comment))

  def ToPrettyXml(self, doc, **kwargs):
    # return doc.toprettyxml(indent='  ')
    # The above pretty-printer does not print the doctype and adds spaces
    # around texts, e.g.:
    #  <string>
    #    value of the string
    #  </string>
    # This is problematic both for the OSX Workgroup Manager (plist files) and
    # the Windows Group Policy Editor (admx files). What they need instead:
    #  <string>value of string</string>
    # So we use the poor man's pretty printer here. It assumes that there are
    # no mixed-content nodes.
    # Get all the XML content in a one-line string.
    xml = doc.toxml(**kwargs)
    # Determine where the line breaks will be. (They will only be between tags.)
    lines = xml[1:len(xml) - 1].split('><')
    indent = ''
    res = ''
    # Determine indent for each line.
    for i, line in enumerate(lines):
      if line[0] == '/':
        # If the current line starts with a closing tag, decrease indent before
        # printing.
        indent = indent[2:]
      lines[i] = indent + '<' + line + '>'
      if (line[0] not in ['/', '?', '!'] and '</' not in line and
          line[len(line) - 1] != '/'):
        # If the current line starts with an opening tag and does not conatin a
        # closing tag, increase indent after the line is printed.
        indent += '  '
    # Reconstruct XML text from the lines.
    return '\n'.join(lines)