comparison env/lib/python3.7/site-packages/planemo/xml/validation.py @ 0:26e78fe6e8c4 draft

"planemo upload commit c699937486c35866861690329de38ec1a5d9f783"
author shellac
date Sat, 02 May 2020 07:14:21 -0400
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:26e78fe6e8c4
1 """Module describing abstractions for validating XML content."""
2 import abc
3 import subprocess
4 from collections import namedtuple
5
6 from galaxy.tool_util.deps.commands import which
7 from galaxy.util import unicodify
8 try:
9 from lxml import etree
10 except ImportError:
11 etree = None
12
13 XMLLINT_COMMAND = "xmllint --noout --schema {0} {1} 2>&1"
14 INSTALL_VALIDATOR_MESSAGE = ("This feature requires an external dependency "
15 "to function, pleaes install xmllint (e.g 'brew "
16 "install libxml2' or 'apt-get install "
17 "libxml2-utils'.")
18
19
20 class XsdValidator(object):
21 """Class allowing validation of XML files against XSD schema."""
22
23 __metaclass__ = abc.ABCMeta
24
25 @abc.abstractmethod
26 def validate(self, schema_path, target_path):
27 """Validate ``target_path`` against ``schema_path``.
28
29 :return type: ValidationResult
30 """
31
32 @abc.abstractmethod
33 def enabled(self):
34 """Return True iff system has dependencies for this validator.
35
36 :return type: bool
37 """
38
39
40 ValidationResult = namedtuple("ValidationResult", ["passed", "output"])
41
42
43 class LxmlValidator(XsdValidator):
44 """Validate XSD files using lxml library."""
45
46 def validate(self, schema_path, target_path):
47 try:
48 xsd_doc = etree.parse(schema_path)
49 xsd = etree.XMLSchema(xsd_doc)
50 xml = etree.parse(target_path)
51 passed = xsd.validate(xml)
52 return ValidationResult(passed, xsd.error_log)
53 except etree.XMLSyntaxError as e:
54 return ValidationResult(False, unicodify(e))
55
56 def enabled(self):
57 return etree is not None
58
59
60 class XmllintValidator(XsdValidator):
61 """Validate XSD files with the external tool xmllint."""
62
63 def validate(self, schema_path, target_path):
64 command = XMLLINT_COMMAND.format(schema_path, target_path)
65 p = subprocess.Popen(command, stdout=subprocess.PIPE, shell=True)
66 stdout, _ = p.communicate()
67 passed = p.returncode == 0
68 return ValidationResult(passed, stdout)
69
70 def enabled(self):
71 return bool(which("xmllint"))
72
73
74 VALIDATORS = [LxmlValidator(), XmllintValidator()]
75
76
77 def get_validator(require=True):
78 """Return a :class:`XsdValidator` object based on available dependencies."""
79 for validator in VALIDATORS:
80 if validator.enabled():
81 return validator
82
83 if require:
84 raise Exception(INSTALL_VALIDATOR_MESSAGE)
85
86 return None
87
88
89 __all__ = (
90 "get_validator",
91 "XsdValidator",
92 )