1# Copyright (c) 2010-2024 openpyxl
2
3"""
4XML compatibility functions
5"""
6
7# Python stdlib imports
8import re
9from functools import partial
10
11from openpyxl import DEFUSEDXML, LXML
12
13if LXML is True:
14 from lxml.etree import (
15 Element,
16 SubElement,
17 register_namespace,
18 QName,
19 xmlfile,
20 XMLParser,
21 )
22 from lxml.etree import fromstring, tostring
23 # do not resolve entities
24 safe_parser = XMLParser(resolve_entities=False)
25 fromstring = partial(fromstring, parser=safe_parser)
26
27else:
28 from xml.etree.ElementTree import (
29 Element,
30 SubElement,
31 fromstring,
32 tostring,
33 QName,
34 register_namespace
35 )
36 from et_xmlfile import xmlfile
37 if DEFUSEDXML is True:
38 from defusedxml.ElementTree import fromstring
39
40from xml.etree.ElementTree import iterparse
41if DEFUSEDXML is True:
42 from defusedxml.ElementTree import iterparse
43
44from openpyxl.xml.constants import (
45 CHART_NS,
46 DRAWING_NS,
47 SHEET_DRAWING_NS,
48 CHART_DRAWING_NS,
49 SHEET_MAIN_NS,
50 REL_NS,
51 VTYPES_NS,
52 COREPROPS_NS,
53 CUSTPROPS_NS,
54 DCTERMS_NS,
55 DCTERMS_PREFIX,
56 XML_NS
57)
58
59register_namespace(DCTERMS_PREFIX, DCTERMS_NS)
60register_namespace('dcmitype', 'http://purl.org/dc/dcmitype/')
61register_namespace('cp', COREPROPS_NS)
62register_namespace('c', CHART_NS)
63register_namespace('a', DRAWING_NS)
64register_namespace('s', SHEET_MAIN_NS)
65register_namespace('r', REL_NS)
66register_namespace('vt', VTYPES_NS)
67register_namespace('xdr', SHEET_DRAWING_NS)
68register_namespace('cdr', CHART_DRAWING_NS)
69register_namespace('xml', XML_NS)
70register_namespace('cust', CUSTPROPS_NS)
71
72
73tostring = partial(tostring, encoding="utf-8")
74
75NS_REGEX = re.compile("({(?P<namespace>.*)})?(?P<localname>.*)")
76
77def localname(node):
78 if callable(node.tag):
79 return "comment"
80 m = NS_REGEX.match(node.tag)
81 return m.group('localname')
82
83
84def whitespace(node):
85 stripped = node.text.strip()
86 if stripped and node.text != stripped:
87 node.set("{%s}space" % XML_NS, "preserve")