OLD | NEW |
1 # Copyright (c) 2011 Google Inc. All rights reserved. | 1 # Copyright (c) 2011 Google Inc. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 import re | 5 import re |
6 import os | 6 import os |
7 | 7 |
| 8 try: |
| 9 reduce |
| 10 except NameError: |
| 11 from functools import reduce |
8 | 12 |
9 def XmlToString(content, encoding='utf-8', pretty=False): | 13 def XmlToString(content, encoding='utf-8', pretty=False): |
10 """ Writes the XML content to disk, touching the file only if it has changed. | 14 """ Writes the XML content to disk, touching the file only if it has changed. |
11 | 15 |
12 Visual Studio files have a lot of pre-defined structures. This function makes | 16 Visual Studio files have a lot of pre-defined structures. This function makes |
13 it easy to represent these structures as Python data structures, instead of | 17 it easy to represent these structures as Python data structures, instead of |
14 having to create a lot of function calls. | 18 having to create a lot of function calls. |
15 | 19 |
16 Each XML element of the content is represented as a list composed of: | 20 Each XML element of the content is represented as a list composed of: |
17 1. The name of the element, a string, | 21 1. The name of the element, a string, |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
72 new_line = '' | 76 new_line = '' |
73 name = specification[0] | 77 name = specification[0] |
74 if not isinstance(name, str): | 78 if not isinstance(name, str): |
75 raise Exception('The first item of an EasyXml specification should be ' | 79 raise Exception('The first item of an EasyXml specification should be ' |
76 'a string. Specification was ' + str(specification)) | 80 'a string. Specification was ' + str(specification)) |
77 xml_parts.append(indentation + '<' + name) | 81 xml_parts.append(indentation + '<' + name) |
78 | 82 |
79 # Optionally in second position is a dictionary of the attributes. | 83 # Optionally in second position is a dictionary of the attributes. |
80 rest = specification[1:] | 84 rest = specification[1:] |
81 if rest and isinstance(rest[0], dict): | 85 if rest and isinstance(rest[0], dict): |
82 for at, val in sorted(rest[0].iteritems()): | 86 for at, val in sorted(rest[0].items()): |
83 xml_parts.append(' %s="%s"' % (at, _XmlEscape(val, attr=True))) | 87 xml_parts.append(' %s="%s"' % (at, _XmlEscape(val, attr=True))) |
84 rest = rest[1:] | 88 rest = rest[1:] |
85 if rest: | 89 if rest: |
86 xml_parts.append('>') | 90 xml_parts.append('>') |
87 all_strings = reduce(lambda x, y: x and isinstance(y, str), rest, True) | 91 all_strings = reduce(lambda x, y: x and isinstance(y, str), rest, True) |
88 multi_line = not all_strings | 92 multi_line = not all_strings |
89 if multi_line and new_line: | 93 if multi_line and new_line: |
90 xml_parts.append(new_line) | 94 xml_parts.append(new_line) |
91 for child_spec in rest: | 95 for child_spec in rest: |
92 # If it's a string, append a text node. | 96 # If it's a string, append a text node. |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
148 | 152 |
149 def _XmlEscape(value, attr=False): | 153 def _XmlEscape(value, attr=False): |
150 """ Escape a string for inclusion in XML.""" | 154 """ Escape a string for inclusion in XML.""" |
151 def replace(match): | 155 def replace(match): |
152 m = match.string[match.start() : match.end()] | 156 m = match.string[match.start() : match.end()] |
153 # don't replace single quotes in attrs | 157 # don't replace single quotes in attrs |
154 if attr and m == "'": | 158 if attr and m == "'": |
155 return m | 159 return m |
156 return _xml_escape_map[m] | 160 return _xml_escape_map[m] |
157 return _xml_escape_re.sub(replace, value) | 161 return _xml_escape_re.sub(replace, value) |
OLD | NEW |