Skip to content

Commit

Permalink
Merge pull request #1482 from dmach/util-xml
Browse files Browse the repository at this point in the history
Move xml_indent, xml_quote and xml_unquote to osc.util.xml module
  • Loading branch information
dmach authored Feb 12, 2024
2 parents ff31a5c + 556c97d commit d1f4522
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 58 deletions.
42 changes: 4 additions & 38 deletions osc/_private/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
import xml.sax.saxutils
from xml.etree import ElementTree as ET

from ..util.xml import xml_escape
from ..util.xml import xml_indent
from ..util.xml import xml_unescape


def get(apiurl, path, query=None):
"""
Expand Down Expand Up @@ -205,41 +209,3 @@ def write_xml_node_to_file(node, path, indent=True):
if indent:
xml_indent(node)
ET.ElementTree(node).write(path)


def xml_escape(string):
"""
Escape the string so it's safe to use in XML and xpath.
"""
entities = {
"\"": """,
"'": "'",
}
if isinstance(string, bytes):
return xml.sax.saxutils.escape(string.decode("utf-8"), entities=entities).encode("utf-8")
return xml.sax.saxutils.escape(string, entities=entities)


def xml_unescape(string):
"""
Decode XML entities in the string.
"""
entities = {
""": "\"",
"'": "'",
}
if isinstance(string, bytes):
return xml.sax.saxutils.unescape(string.decode("utf-8"), entities=entities).encode("utf-8")
return xml.sax.saxutils.unescape(string, entities=entities)


def xml_indent(root):
"""
Indent XML so it looks pretty after printing or saving to file.
"""
if hasattr(ET, "indent"):
# ElementTree supports indent() in Python 3.9 and newer
ET.indent(root)
else:
from .. import core as osc_core
osc_core.xmlindent(root)
21 changes: 1 addition & 20 deletions osc/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
from .connection import http_request, http_GET, http_POST, http_PUT, http_DELETE
from .store import Store
from .util.helper import decode_list, decode_it, raw_input, _html_escape
from .util.xml import xml_indent_compat as xmlindent


ET_ENCODING = "unicode"
Expand Down Expand Up @@ -636,26 +637,6 @@ def isexpanded(self):
def haserror(self):
return self.error is not None

# http://effbot.org/zone/element-lib.htm#prettyprint


def xmlindent(elem, level=0):
i = "\n" + level * " "
if isinstance(elem, ET.ElementTree):
elem = elem.getroot()
if len(elem):
if not elem.text or not elem.text.strip():
elem.text = i + " "
for e in elem:
xmlindent(e, level + 1)
if not e.tail or not e.tail.strip():
e.tail = i + " "
if not e.tail or not e.tail.strip():
e.tail = i
else:
if level and (not elem.tail or not elem.tail.strip()):
elem.tail = i


class Project:
"""
Expand Down
81 changes: 81 additions & 0 deletions osc/util/xml.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
"""
Functions that manipulate with XML.
"""


import xml.sax.saxutils
from xml.etree import ElementTree as ET


def xml_escape(string):
"""
Escape the string so it's safe to use in XML and xpath.
"""
entities = {
'"': """,
"'": "'",
}
if isinstance(string, bytes):
return xml.sax.saxutils.escape(string.decode("utf-8"), entities=entities).encode("utf-8")
return xml.sax.saxutils.escape(string, entities=entities)


def xml_unescape(string):
"""
Decode XML entities in the string.
"""
entities = {
""": '"',
"'": "'",
}
if isinstance(string, bytes):
return xml.sax.saxutils.unescape(string.decode("utf-8"), entities=entities).encode("utf-8")
return xml.sax.saxutils.unescape(string, entities=entities)


def xml_strip_text(node):
"""
Recursively strip inner text in nodes:
- if text contains only whitespaces
- if node contains child nodes
"""
if node.text and not node.text.strip():
node.text = None
elif len(node) != 0:
node.text = None
for child in node:
xml_strip_text(child)


def xml_indent_compat(elem, level=0):
"""
XML indentation code for python < 3.9.
Source: http://effbot.org/zone/element-lib.htm#prettyprint
"""
i = "\n" + level * " "
if isinstance(elem, ET.ElementTree):
elem = elem.getroot()
if len(elem):
if not elem.text or not elem.text.strip():
elem.text = i + " "
for e in elem:
xml_indent_compat(e, level + 1)
if not e.tail or not e.tail.strip():
e.tail = i + " "
if not e.tail or not e.tail.strip():
e.tail = i
else:
if level and (not elem.tail or not elem.tail.strip()):
elem.tail = i


def xml_indent(root):
"""
Indent XML so it looks pretty after printing or saving to file.
"""
if hasattr(ET, "indent"):
# ElementTree supports indent() in Python 3.9 and newer
xml_strip_text(root)
ET.indent(root)
else:
xml_indent_compat(root)

0 comments on commit d1f4522

Please sign in to comment.