summaryrefslogtreecommitdiff
path: root/odoo/tools/xml_utils.py
diff options
context:
space:
mode:
authorwilliam <wan@odoo.com>2020-07-06 11:49:20 +0000
committerwilliam <wan@odoo.com>2020-07-10 14:18:12 +0000
commit048c7fef6716e7f459e9f88c10e03a1babf98fae (patch)
tree7625dad4f9e562aa6cb9f92b57e4dc4badd9b98c /odoo/tools/xml_utils.py
parenta0f45bab76e7c424c56a255867842cc6df41458d (diff)
[IMP] base: _check_with_xsd from ir.attachment
Search the xsd files from in the database. To enable this option, the Environment should be passed to the optional `env` parameter. Both the XSD root and the XSD imported by the root and the recusrively imported files will be searched in the database. X-original-commit: 06a35f2e11230db81b8c21696d228097b31cf649
Diffstat (limited to 'odoo/tools/xml_utils.py')
-rw-r--r--odoo/tools/xml_utils.py46
1 files changed, 40 insertions, 6 deletions
diff --git a/odoo/tools/xml_utils.py b/odoo/tools/xml_utils.py
index eb5b8b203bf..513aa207663 100644
--- a/odoo/tools/xml_utils.py
+++ b/odoo/tools/xml_utils.py
@@ -1,22 +1,56 @@
# -*- coding: utf-8 -*-
+import base64
+from io import BytesIO
from lxml import etree
-from odoo.tools.misc import file_open
+
from odoo.exceptions import UserError
+
+class odoo_resolver(etree.Resolver):
+ """Odoo specific file resolver that can be added to the XML Parser.
+
+ It will search filenames in the ir.attachments
+ """
+
+ def __init__(self, env):
+ super().__init__()
+ self.env = env
+
+ def resolve(self, url, id, context):
+ """Search url in ``ir.attachment`` and return the resolved content."""
+ attachment = self.env['ir.attachment'].search([('name', '=', url)])
+ if attachment:
+ return self.resolve_string(base64.b64decode(attachment.datas), context)
+
+
def check_with_xsd(tree_or_str, stream):
raise UserError("Method 'check_with_xsd' deprecated ")
+def _check_with_xsd(tree_or_str, stream, env=None):
+ """Check an XML against an XSD schema.
-def _check_with_xsd(tree_or_str, stream):
+ This will raise a UserError if the XML file is not valid according to the
+ XSD file.
+ :param tree_or_str (etree, str): representation of the tree to be checked
+ :param stream (io.IOBase, str): the byte stream used to build the XSD schema.
+ If env is given, it can also be the name of an attachment in the filestore
+ :param env (odoo.api.Environment): If it is given, it enables resolving the
+ imports of the schema in the filestore with ir.attachments.
+ """
if not isinstance(tree_or_str, etree._Element):
tree_or_str = etree.fromstring(tree_or_str)
- xml_schema_doc = etree.parse(stream)
- xsd_schema = etree.XMLSchema(xml_schema_doc)
+ parser = etree.XMLParser()
+ if env:
+ parser.resolvers.add(odoo_resolver(env))
+ if isinstance(stream, str) and stream.endswith('.xsd'):
+ attachment = env['ir.attachment'].search([('name', '=', stream)])
+ if not attachment:
+ raise FileNotFoundError()
+ stream = BytesIO(base64.b64decode(attachment.datas))
+ xsd_schema = etree.XMLSchema(etree.parse(stream, parser=parser))
try:
xsd_schema.assertValid(tree_or_str)
except etree.DocumentInvalid as xml_errors:
- #import UserError only here to avoid circular import statements with tools.func being imported in exceptions.py
- from odoo.exceptions import UserError
raise UserError('\n'.join(str(e) for e in xml_errors.error_log))