You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

71 lines
2.5 KiB

import os.path
import unicodedata
from lxml import etree
from StringIO import StringIO
from lxml import objectify
import xml.etree.ElementTree as ET
from jinja2 import Environment, FileSystemLoader
from . import filters
def render_xml(path, template_name, **nfe):
env = Environment(
loader=FileSystemLoader(path), extensions=['jinja2.ext.with_'])
env.filters["normalize"] = filters.normalize_str
env.filters["format_percent"] = filters.format_percent
env.filters["format_datetime"] = filters.format_datetime
env.filters["format_date"] = filters.format_date
template = env.get_template(template_name)
xml = template.render(**nfe)
xml = xml.replace('&', '&')
parser = etree.XMLParser(remove_blank_text=True, remove_comments=True)
elem = etree.fromstring(xml, parser=parser)
return etree.tostring(elem)
def sanitize_response(response):
response = unicode(response)
response = unicodedata.normalize('NFKD', response).encode('ascii',
'ignore')
tree = etree.fromstring(response)
# Remove namespaces inuteis na resposta
for elem in tree.getiterator():
if not hasattr(elem.tag, 'find'):
continue
i = elem.tag.find('}')
if i >= 0:
elem.tag = elem.tag[i+1:]
objectify.deannotate(tree, cleanup_namespaces=True)
return response, objectify.fromstring(etree.tostring(tree))
def valida_schema(xml, arquivo_xsd):
'''Função que valida um XML usando lxml do Python via arquivo XSD'''
# Carrega o esquema XML do arquivo XSD
xsd = etree.XMLSchema(file=arquivo_xsd)
# Converte o XML passado em XML do lxml
xml = etree.fromstring(str(xml))
# Verifica a validade do xml
erros = []
if not xsd(xml):
# Caso tenha erros, cria uma lista de erros
for erro in xsd.error_log:
erros.append({
'message': erro.message,
'domain': erro.domain,
'type': erro.type,
'level': erro.level,
'line': erro.line,
'column': erro.column,
'filename': erro.filename,
'domain_name': erro.domain_name,
'type_name': erro.type_name,
'level_name': erro.level_name
})
# Retorna os erros, sendo uma lista vazia caso não haja erros
return erros