195640e3a20adea634b4df4ccf8c93f411184c438joi@chromium.org#!/usr/bin/env python 295640e3a20adea634b4df4ccf8c93f411184c438joi@chromium.org# Copyright (c) 2012 The Chromium Authors. All rights reserved. 301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org# Use of this source code is governed by a BSD-style license that can be 401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org# found in the LICENSE file. 501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.orgfrom grit.format.policy_templates.writers import template_writer 801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 1001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.orgclass XMLFormattedWriter(template_writer.TemplateWriter): 1101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org '''Helper class for generating XML-based templates. 1201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org ''' 1301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 1401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org def AddElement(self, parent, name, attrs=None, text=None): 1501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org ''' 1601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org Adds a new XML Element as a child to an existing element or the Document. 1701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 1801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org Args: 1901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org parent: An XML element or the document, where the new element will be 2001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org added. 2101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org name: The name of the new element. 2201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org attrs: A dictionary of the attributes' names and values for the new 2301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org element. 2401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org text: Text content for the new element. 2501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 2601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org Returns: 2701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org The created new element. 2801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org ''' 2901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org if attrs == None: 3001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org attrs = {} 3101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 3201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org doc = parent.ownerDocument 3301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org element = doc.createElement(name) 3401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org for key, value in attrs.iteritems(): 3501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org element.setAttribute(key, value) 3601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org if text: 3701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org element.appendChild(doc.createTextNode(text)) 3801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org parent.appendChild(element) 3901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org return element 4001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 4101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org def AddText(self, parent, text): 4201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org '''Adds text to a parent node. 4301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org ''' 4401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org doc = parent.ownerDocument 4501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org parent.appendChild(doc.createTextNode(text)) 4601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 4701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org def AddAttribute(self, parent, name, value): 4801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org '''Adds a new attribute to the parent Element. If an attribute with the 4901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org given name already exists then it will be replaced. 5001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org ''' 5101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org doc = parent.ownerDocument 5201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org attribute = doc.createAttribute(name) 5301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org attribute.value = value 5401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org parent.setAttributeNode(attribute) 5501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 566fb6d62a2a05b7a7c268cc4e6bf0452e376e1990joaodasilva@chromium.org def AddComment(self, parent, comment): 576fb6d62a2a05b7a7c268cc4e6bf0452e376e1990joaodasilva@chromium.org '''Adds a comment node.''' 586fb6d62a2a05b7a7c268cc4e6bf0452e376e1990joaodasilva@chromium.org parent.appendChild(parent.ownerDocument.createComment(comment)) 596fb6d62a2a05b7a7c268cc4e6bf0452e376e1990joaodasilva@chromium.org 606fb6d62a2a05b7a7c268cc4e6bf0452e376e1990joaodasilva@chromium.org def ToPrettyXml(self, doc, **kwargs): 6101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org # return doc.toprettyxml(indent=' ') 6201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org # The above pretty-printer does not print the doctype and adds spaces 6301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org # around texts, e.g.: 6401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org # <string> 6501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org # value of the string 6601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org # </string> 6701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org # This is problematic both for the OSX Workgroup Manager (plist files) and 6801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org # the Windows Group Policy Editor (admx files). What they need instead: 6901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org # <string>value of string</string> 7001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org # So we use the poor man's pretty printer here. It assumes that there are 7101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org # no mixed-content nodes. 7201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org # Get all the XML content in a one-line string. 736fb6d62a2a05b7a7c268cc4e6bf0452e376e1990joaodasilva@chromium.org xml = doc.toxml(**kwargs) 7401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org # Determine where the line breaks will be. (They will only be between tags.) 7501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org lines = xml[1:len(xml) - 1].split('><') 7601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org indent = '' 7701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org res = '' 7801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org # Determine indent for each line. 79b9161407f737461b5db16a29782f8a31d19e602dbenrg@chromium.org for i, line in enumerate(lines): 8001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org if line[0] == '/': 8101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org # If the current line starts with a closing tag, decrease indent before 8201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org # printing. 8301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org indent = indent[2:] 8401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org lines[i] = indent + '<' + line + '>' 8501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org if (line[0] not in ['/', '?', '!'] and '</' not in line and 8601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org line[len(line) - 1] != '/'): 8701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org # If the current line starts with an opening tag and does not conatin a 8801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org # closing tag, increase indent after the line is printed. 8901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org indent += ' ' 9001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org # Reconstruct XML text from the lines. 9101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org return '\n'.join(lines) 92