functions.py 2.0 KB

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