Co-authored-by: Adam Bem <adam.bem@zoho.eu> Reviewed-on: R11/release11-tools-web#99
This commit is contained in:
@@ -1,31 +1,18 @@
|
||||
from lxml import etree
|
||||
from io import BytesIO
|
||||
|
||||
|
||||
def prettify(source: str) -> str:
|
||||
"""Method used to pretty format given XML
|
||||
def formatXML(source: str, prettify: bool) -> str:
|
||||
"""Method used to format XML
|
||||
|
||||
:param source: XML
|
||||
:return: prettified XML
|
||||
:param source: XML to format
|
||||
:param prettify: sets if XML must be prettified
|
||||
(added indentations etc.) or not
|
||||
:return: formatted XML
|
||||
"""
|
||||
prolog = ""
|
||||
prolog_start = source.find("<?")
|
||||
|
||||
if prolog_start != -1:
|
||||
prolog_end = source.find("?>") + 2
|
||||
prolog = source[prolog_start:prolog_end] + "\n"
|
||||
source = source[prolog_end: ]
|
||||
|
||||
parser = etree.XMLParser(remove_blank_text=True)
|
||||
xml = etree.fromstring(source, parser=parser)
|
||||
return prolog + etree.tostring(xml, pretty_print=True).decode()
|
||||
|
||||
def minimize(source: str) -> str:
|
||||
"""Method used to minimize XML by deleting not needed whitespaces.
|
||||
|
||||
:param source: XML
|
||||
:return: minimized XML
|
||||
"""
|
||||
|
||||
# Prolog is removed when XML is parsed
|
||||
# so program has to copy it
|
||||
prolog = ""
|
||||
prolog_start = source.find("<?")
|
||||
|
||||
@@ -34,9 +21,14 @@ def minimize(source: str) -> str:
|
||||
prolog = source[prolog_start:prolog_end]
|
||||
source = source[prolog_end: ]
|
||||
|
||||
byte_input = BytesIO(source.encode("utf-8"))
|
||||
parser = etree.XMLParser(remove_blank_text=True)
|
||||
xml = etree.fromstring(source, parser=parser)
|
||||
return prolog + etree.tostring(xml, pretty_print=False).decode()
|
||||
xml = etree.parse(byte_input, parser=parser)
|
||||
|
||||
if prettify:
|
||||
prolog += "\n"
|
||||
|
||||
return prolog + etree.tostring(xml, pretty_print=prettify).decode()
|
||||
|
||||
|
||||
def xpath(source: str, xpath: str) -> str:
|
||||
@@ -48,8 +40,8 @@ def xpath(source: str, xpath: str) -> str:
|
||||
:return: Nodes selected using XPath
|
||||
"""
|
||||
|
||||
|
||||
root = etree.XML(source)
|
||||
byte_input = BytesIO(source.encode("utf-8"))
|
||||
root = etree.parse(byte_input).getroot()
|
||||
nsmap = root.nsmap
|
||||
|
||||
# LXML doesn't accept empty (None) namespace prefix,
|
||||
@@ -61,7 +53,7 @@ def xpath(source: str, xpath: str) -> str:
|
||||
|
||||
# root.xpath can return 4 types: float, string, bool and list.
|
||||
# List is the only one that can't be simply converted to str
|
||||
if result is not list:
|
||||
if type(result) is not list:
|
||||
return str(result)
|
||||
else:
|
||||
result_string = ""
|
||||
@@ -78,9 +70,13 @@ def xsd(source: str, xsd: str) -> bool:
|
||||
:param xsd: XSD schema to validate XML against
|
||||
:return: Message saying, if the validation was successful or not
|
||||
"""
|
||||
xml_schema = etree.XMLSchema(etree.XML(xsd))
|
||||
|
||||
xml = etree.XML(source)
|
||||
schema_input = BytesIO(xsd.encode("utf-8"))
|
||||
xml_schema = etree.XMLSchema(etree.parse(schema_input).getroot())
|
||||
|
||||
document_input = BytesIO(source.encode("utf-8"))
|
||||
xml = etree.parse(document_input).getroot()
|
||||
|
||||
if xml_schema.validate(xml):
|
||||
return "XML is valid."
|
||||
else:
|
||||
@@ -89,16 +85,17 @@ def xsd(source: str, xsd: str) -> bool:
|
||||
|
||||
def xslt(source: str, xslt: str) -> str:
|
||||
"""
|
||||
Method used to transformate XML string using XSLT
|
||||
Method used to transform XML string using XSLT
|
||||
|
||||
:param source: XML string to transform
|
||||
:param xslt: XSLT string used to transformate XML
|
||||
:param xslt: XSLT string used to transform XML
|
||||
:return: Result of transformation
|
||||
"""
|
||||
xslt_transform = etree.XSLT(etree.XML(xslt))
|
||||
xslt_input = BytesIO(xslt.encode("utf-8"))
|
||||
xslt_transform = etree.XSLT(etree.parse(xslt_input))
|
||||
|
||||
xml = etree.XML(source)
|
||||
document_input = BytesIO(source.encode("utf-8"))
|
||||
xml = etree.parse(document_input).getroot()
|
||||
|
||||
transformated = xslt_transform(xml)
|
||||
print(transformated)
|
||||
return str(transformated)
|
||||
transformed = str(xslt_transform(xml))
|
||||
return formatXML(transformed, True)
|
||||
@@ -15,43 +15,6 @@ cors = CORS(app, resource={
|
||||
}
|
||||
})
|
||||
|
||||
def format_xml(request: request, type: str) -> str:
|
||||
"""Function to format XML
|
||||
|
||||
:param request: Received request
|
||||
:param type: Type of needed processing: xsd, xslt or xpath
|
||||
:raises ValueError: is raised when type is different than those provided above
|
||||
:return: response JSON converted to string and response code
|
||||
"""
|
||||
start = time.time_ns()
|
||||
code = 200
|
||||
response_json = dict()
|
||||
try:
|
||||
request_data = json.loads(request.get_data(as_text=True))
|
||||
data = request_data['data']
|
||||
process = request_data['process']
|
||||
if (type == "prettify"):
|
||||
response_json['result'] = Parser.xsd(data, process)
|
||||
elif (type == "minimize"):
|
||||
response_json['result'] = Parser.xslt(data, process)
|
||||
else:
|
||||
raise ValueError("Valid operation types are: prettify, minimize")
|
||||
|
||||
response_json['status'] = "OK"
|
||||
except KeyError as e:
|
||||
response_json['result'] = "Missing key: " + str(e)
|
||||
response_json['status'] = "ERR"
|
||||
code = 400
|
||||
except Exception as e:
|
||||
response_json['result'] = str(e)
|
||||
response_json['status'] = "ERR"
|
||||
code = 400
|
||||
finally:
|
||||
exec_time = (time.time_ns() - start) / 10**6
|
||||
response_json['time'] = f"{exec_time:.03f}"
|
||||
response_json['processor'] = "libxml2 over lxml"
|
||||
return json.dumps(response_json), code
|
||||
|
||||
def process_xml(request: request, type: str) -> str:
|
||||
"""Function to process
|
||||
|
||||
@@ -74,9 +37,9 @@ def process_xml(request: request, type: str) -> str:
|
||||
elif (type == "xpath"):
|
||||
response_json['result'] = Parser.xpath(data, process)
|
||||
elif (type == "prettify"):
|
||||
response_json['result'] = Parser.prettify(data)
|
||||
response_json['result'] = Parser.formatXML(data, True)
|
||||
elif (type == "minimize"):
|
||||
response_json['result'] = Parser.minimize(data)
|
||||
response_json['result'] = Parser.formatXML(data, False)
|
||||
else:
|
||||
raise ValueError("Valid operation types are: xsd, xslt, xpath")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user