Coverage for gws-app/gws/lib/xmlx/util.py: 96%
27 statements
« prev ^ index » next coverage.py v7.16.2, created at 2026-10-05 13:35 +0200
« prev ^ index » next coverage.py v7.16.2, created at 2026-10-05 13:35 +0200
1"""Value conversion and escaping for XML output."""
3import gws.lib.datetimex as dtx
6def atom_to_string(s) -> tuple[str, bool]:
7 """Convert a primitive value to a string for XML output.
9 ``None`` becomes an empty string, numbers and booleans are lowercased (``true``, ``false``),
10 datetimes and dates are written in ISO format.
12 Args:
13 s: The value.
15 Returns:
16 A tuple of the string and a flag that is ``False`` if the value is not a primitive value.
17 """
19 if s is None:
20 return '', True
22 if isinstance(s, str):
23 return s, True
25 if isinstance(s, (int, float, bool)):
26 return str(s).lower(), True
28 if isinstance(s, dtx.dt.datetime):
29 return dtx.to_iso_string(s, with_tz=':'), True
31 if isinstance(s, dtx.dt.date):
32 return dtx.to_iso_date_string(s), True
34 return '', False
37def escape_text(s: str) -> str:
38 """Escape ``&``, ``<`` and ``>`` for XML text content.
40 Args:
41 s: The text.
43 Returns:
44 The escaped text.
45 """
47 s = s.replace('&', '&')
48 s = s.replace('>', '>')
49 s = s.replace('<', '<')
50 return s
53def escape_attribute(s: str) -> str:
54 """Escape a string for a double-quoted XML attribute value.
56 Escapes ``&``, ``"``, ``<``, ``>``, tabs and line breaks.
58 Args:
59 s: The value.
61 Returns:
62 The escaped value.
63 """
65 s = s.replace('&', '&')
66 s = s.replace('"', '"')
67 s = s.replace('>', '>')
68 s = s.replace('<', '<')
69 s = s.replace('\t', '	')
70 s = s.replace('\r', '
')
71 s = s.replace('\n', '
')
72 return s