# Copyright (c) 2011 Google Inc. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file.
import re import os import locale import sys
try: # reduce moved to functools in python3.
reduce except NameError: from functools import reduce
def XmlToString(content, encoding='utf-8', pretty=False): """ Writes the XML content to disk, touching the file only if it has changed.
Visual Studio files have a lot of pre-defined structures. This function makes
it easy to represent these structures as Python data structures, instead of
having to create a lot of function calls.
Each XML element of the content is represented as a list composed of:
1. The name of the element, a string,
2. The attributes of the element, a dictionary (optional), and
3+. The content of the element, if any. Strings are simple text nodes and
lists are child elements.
Example 1:
<test/>
becomes
['test']
Example 2:
<myelement a='value1' b='value2'>
<childtype>This is</childtype>
<childtype>it!</childtype>
</myelement>
Args:
content: The structured content to be converted.
encoding: The encoding to report on the first XML line.
pretty: Trueif we want pretty printing with indents and new lines.
Returns:
The XML content as a string. """ # We create a huge list of all the elements of the file.
xml_parts = ['' % encoding] if pretty:
xml_parts.append('\n')
_ConstructContentList(xml_parts, content, pretty)
# Convert it to a string return''.join(xml_parts)
def _ConstructContentList(xml_parts, specification, pretty, level=0): """ Appends the XML parts corresponding to the specification.
Args:
xml_parts: A list of XML parts to be appended to.
specification: The specification of the element. See EasyXml docs.
pretty: Trueif we want pretty printing with indents and new lines.
level: Indentation level. """ # The first item in a specification is the name of the element. if pretty:
indentation = ' ' * level
new_line = '\n' else:
indentation = ''
new_line = ''
name = specification[0] ifnot isinstance(name, str): raise Exception('The first item of an EasyXml specification should be ' 'a string. Specification was ' + str(specification))
xml_parts.append(indentation + '<' + name)
# Optionally in second position is a dictionary of the attributes.
rest = specification[1:] if rest and isinstance(rest[0], dict): for at, val in sorted(rest[0].items()):
xml_parts.append(' %s="%s"' % (at, _XmlEscape(val, attr=True)))
rest = rest[1:] if rest:
xml_parts.append('>')
all_strings = reduce(lambda x, y: x and isinstance(y, str), rest, True)
multi_line = not all_strings if multi_line and new_line:
xml_parts.append(new_line) for child_spec in rest: # If it's a string, append a text node. # Otherwise recurse over that child definition if isinstance(child_spec, str):
xml_parts.append(_XmlEscape(child_spec)) else:
_ConstructContentList(xml_parts, child_spec, pretty, level + 1) if multi_line and indentation:
xml_parts.append(indentation)
xml_parts.append('%s>%s' % (name, new_line)) else:
xml_parts.append('/>%s' % new_line)
def WriteXmlIfChanged(content, path, encoding='utf-8', pretty=False,
win32=False): """ Writes the XML content to disk, touching the file only if it has changed.
Args:
content: The structured content to be written.
path: Location of the file.
encoding: The encoding to report on the first line of the XML file.
pretty: Trueif we want pretty printing with indents and new lines. """
xml_string = XmlToString(content, encoding, pretty) if win32 and os.linesep != '\r\n':
xml_string = xml_string.replace('\n', '\r\n')
default_encoding = locale.getdefaultlocale()[1] if default_encoding and default_encoding.upper() != encoding.upper(): try:
xml_string = xml_string.decode(default_encoding).encode(encoding) except AttributeError: pass
# Get the old content try:
f = open(path, 'r')
existing = f.read()
f.close() except:
existing = None
# It has changed, write it if existing != xml_string:
f = open(path, 'w')
f.write(xml_string)
f.close()
def _XmlEscape(value, attr=False): """ Escape a string for inclusion in XML.""" def replace(match):
m = match.string[match.start() : match.end()] # don't replace single quotes in attrs if attr and m == "'": return m return _xml_escape_map[m] return _xml_escape_re.sub(replace, value)
Messung V0.5
¤ Dauer der Verarbeitung: 0.11 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.