Fixed #94 and done some refactoring (#99)

Co-authored-by: Adam Bem <adam.bem@zoho.eu>
Reviewed-on: R11/release11-tools-web#99
This commit is contained in:
2023-03-03 10:43:32 +01:00
parent fd95d7e845
commit 02f46169d9
13 changed files with 51 additions and 194 deletions

View File

@@ -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)

View File

@@ -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")