xmlutils.py
Go to the documentation of this file.
1 # Copyright (c) 2015, Open Source Robotics Foundation, Inc.
2 # Copyright (c) 2013, Willow Garage, Inc.
3 # All rights reserved.
4 #
5 # Redistribution and use in source and binary forms, with or without
6 # modification, are permitted provided that the following conditions are met:
7 #
8 # * Redistributions of source code must retain the above copyright
9 # notice, this list of conditions and the following disclaimer.
10 # * Redistributions in binary form must reproduce the above copyright
11 # notice, this list of conditions and the following disclaimer in the
12 # documentation and/or other materials provided with the distribution.
13 # * Neither the name of the Open Source Robotics Foundation, Inc.
14 # nor the names of its contributors may be used to endorse or promote
15 # products derived from this software without specific prior
16 # written permission.
17 #
18 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22 # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 # POSSIBILITY OF SUCH DAMAGE.
29 
30 # Authors: Stuart Glaser, William Woodall, Robert Haschke
31 # Maintainer: Morgan Quigley <morgan@osrfoundation.org>
32 
33 import xml
34 from .color import warning
35 
37  c = elt.firstChild
38  while c and c.nodeType != xml.dom.Node.ELEMENT_NODE:
39  c = c.nextSibling
40  return c
41 
42 
44  c = node.nextSibling
45  while c and c.nodeType != xml.dom.Node.ELEMENT_NODE:
46  c = c.nextSibling
47  return c
48 
49 
50 def replace_node(node, by, content_only=False):
51  parent = node.parentNode
52 
53  if by is not None:
54  if not isinstance(by, list):
55  by = [by]
56 
57  # insert new content before node
58  for doc in by:
59  if content_only:
60  c = doc.firstChild
61  while c:
62  n = c.nextSibling
63  parent.insertBefore(c, node)
64  c = n
65  else:
66  parent.insertBefore(doc, node)
67 
68  # remove node
69  parent.removeChild(node)
70 
71 
72 def attribute(tag, a):
73  """
74  Helper function to fetch a single attribute value from tag
75  :param tag (xml.dom.Element): DOM element node
76  :param a (str): attribute name
77  :return: attribute value if present, otherwise None
78  """
79  if tag.hasAttribute(a):
80  # getAttribute returns empty string for non-existent attributes,
81  # which makes it impossible to distinguish with empty values
82  return tag.getAttribute(a)
83  else:
84  return None
85 
86 
87 def opt_attrs(tag, attrs):
88  """
89  Helper routine for fetching optional tag attributes
90  :param tag (xml.dom.Element): DOM element node
91  :param attrs [str]: list of attributes to fetch
92  """
93  return [attribute(tag, a) for a in attrs]
94 
95 
96 def reqd_attrs(tag, attrs):
97  """
98  Helper routine for fetching required tag attributes
99  :param tag (xml.dom.Element): DOM element node
100  :param attrs [str]: list of attributes to fetch
101  :raise RuntimeError: if required attribute is missing
102  """
103  result = opt_attrs(tag, attrs)
104  for (res, name) in zip(result, attrs):
105  if res is None:
106  raise RuntimeError("%s: missing attribute '%s'" % (tag.nodeName, name))
107  return result
108 
109 
110 def check_attrs(tag, required, optional):
111  """
112  Helper routine to fetch required and optional attributes
113  and complain about any additional attributes.
114  :param tag (xml.dom.Element): DOM element node
115  :param required [str]: list of required attributes
116  :param optional [str]: list of optional attributes
117  """
118  result = reqd_attrs(tag, required)
119  result.extend(opt_attrs(tag, optional))
120  allowed = required + optional
121  extra = [a for a in tag.attributes.keys() if a not in allowed and not a.startswith("xmlns:")]
122  if extra:
123  warning("%s: unknown attribute(s): %s" % (tag.nodeName, ', '.join(extra)))
124  return result
125 
126 
127 # Better pretty printing of xml
128 # Taken from http://ronrothman.com/public/leftbraned/xml-dom-minidom-toprettyxml-and-silly-whitespace/
129 def fixed_writexml(self, writer, indent="", addindent="", newl=""):
130  # indent = current indentation
131  # addindent = indentation to add to higher levels
132  # newl = newline string
133  writer.write(indent + "<" + self.tagName)
134 
135  attrs = self._get_attributes()
136  a_names = list(attrs.keys())
137  a_names.sort()
138 
139  for a_name in a_names:
140  writer.write(" %s=\"" % a_name)
141  xml.dom.minidom._write_data(writer, attrs[a_name].value)
142  writer.write("\"")
143  if self.childNodes:
144  if len(self.childNodes) == 1 \
145  and self.childNodes[0].nodeType == xml.dom.minidom.Node.TEXT_NODE:
146  writer.write(">")
147  self.childNodes[0].writexml(writer, "", "", "")
148  writer.write("</%s>%s" % (self.tagName, newl))
149  return
150  writer.write(">%s" % newl)
151  for node in self.childNodes:
152  # skip whitespace-only text nodes
153  if node.nodeType == xml.dom.minidom.Node.TEXT_NODE and \
154  (not node.data or node.data.isspace()):
155  continue
156  node.writexml(writer, indent + addindent, addindent, newl)
157  writer.write("%s</%s>%s" % (indent, self.tagName, newl))
158  else:
159  writer.write("/>%s" % newl)
160 # replace minidom's function with ours
161 xml.dom.minidom.Element.writexml = fixed_writexml
162 
163 
def fixed_writexml(self, writer, indent="", addindent="", newl="")
Definition: xmlutils.py:129
def next_sibling_element(node)
Definition: xmlutils.py:43
def first_child_element(elt)
Definition: xmlutils.py:36
def reqd_attrs(tag, attrs)
Definition: xmlutils.py:96
def replace_node(node, by, content_only=False)
Definition: xmlutils.py:50
def warning(args, kwargs)
Definition: color.py:28
def check_attrs(tag, required, optional)
Definition: xmlutils.py:110
def attribute(tag, a)
Definition: xmlutils.py:72
def opt_attrs(tag, attrs)
Definition: xmlutils.py:87


xacro
Author(s): Stuart Glaser, William Woodall, Robert Haschke
autogenerated on Mon Jun 10 2019 15:46:01