Skip to content

Instantly share code, notes, and snippets.

@Gladozzz
Last active May 11, 2021 08:51
Show Gist options
  • Save Gladozzz/7f26e4071a425b82b5a0e49c8f2ecd0a to your computer and use it in GitHub Desktop.
Save Gladozzz/7f26e4071a425b82b5a0e49c8f2ecd0a to your computer and use it in GitHub Desktop.
simple dirty xml validator tool written in python
import os
import webbrowser
# import subprocess
# from subprocess import Popen,CREATE_NEW_CONSOLE
import lxml.etree # python -m pip install lxml
import tkinter as tk
import tkinter.filedialog as fd
from tkinter import messagebox
from tkinter.scrolledtext import ScrolledText
# command ='cmd'
# prog_start=Popen(command,creationflags=CREATE_NEW_CONSOLE)
# pidvalue=prog_start.pid
# #this will kill the invoked terminal
# subprocess.Popen('taskkill /F /T /PID %i' % pidvalue)
global xml
global xsd
global xml_file
global xsd_file
xml = None
xsd = None
xml_file = None
xsd_file = None
# xml_validator = None
class ToolView(tk.Frame):
global xml
global xsd
global xml_file
global xsd_file
def load_xml(self):
global xml
global xsd
global xml_file
global xsd_file
xml_file = fd.askopenfilename(title='Choose XML', filetypes= [('xml files', '*.xml')], initialdir= os.getcwd())
self.lbl_val_log.delete("1.0","end")
if xml_file:
try:
xml = lxml.etree.parse(xml_file)
self.lbl_xml.config(text = os.path.basename(xml_file), fg="#000000")
except Exception:
self.lbl_xml.config(text = 'Invalid data', fg="#fc0335")
return
def load_xsd(self):
global xml
global xsd
global xml_file
global xsd_file
xsd_file = fd.askopenfilename(title='Choose XSD', filetypes=[('xsd files', '*.xsd')], initialdir= os.getcwd())
self.lbl_val_log.delete("1.0","end")
if xsd_file:
try:
xsd = lxml.etree.XMLSchema(file=xsd_file)
# xsd = lxml.etree.XMLSchema(file="440-П_BVS.xsd")
# root1 = xml.getroot()
# root = root1[0].
# print(xml_data)
self.lbl_xsd.config(text = os.path.basename(xsd_file), fg="#000000")
except Exception:
self.lbl_xsd.config(text = 'Invalid data', fg="#fc0335")
return
def load_xsd_from_path(self, path):
global xml
global xsd
global xml_file
global xsd_file
xsd_file = path
self.lbl_val_log.delete("1.0","end")
if xsd_file:
try:
xsd = lxml.etree.XMLSchema(file=xsd_file)
# xsd = lxml.etree.XMLSchema(file="440-П_BVS.xsd")
# root1 = xml.getroot()
# root = root1[0].
# print(xml_data)
self.lbl_xsd.config(text = os.path.basename(xsd_file), fg="#000000")
except Exception:
self.lbl_xsd.config(text = 'Invalid data', fg="#fc0335")
return
def validate(self):
if self.auto.get():
self.validate_auto()
return
global xml
global xsd
global xml_file
global xsd_file
self.lbl_val_log.delete("1.0","end")
if not xml:
messagebox.showerror("Error", "XML not choosed or invalid")
self.lbl_val_result.config(text = "False", fg="#fc0335")
return
if not xsd:
messagebox.showerror("Error", "XSD not choosed or invalid")
self.lbl_val_result.config(text = "False", fg="#fc0335")
return
xml = lxml.etree.parse(xml_file)
print(xsd_file)
xsd = lxml.etree.XMLSchema(file=xsd_file)
is_valid = xsd.validate(xml)
if is_valid:
self.lbl_val_result.config(text = "True", fg="#03fc07")
else:
self.lbl_val_result.config(text = "False", fg="#fc0335")
self.lbl_val_log.insert('end', xsd.error_log)
if self.notepad.get():
with open('log.txt', "w") as f:
f.writelines(str(xsd.error_log))
f.close()
webbrowser.open("log.txt")
def validate_auto(self):
global xml
global xsd
global xml_file
global xsd_file
self.lbl_val_log.delete("1.0","end")
if not xml:
messagebox.showerror("Error", "XML not choosed or invalid")
self.lbl_val_result.config(text = "False", fg="#fc0335")
return
if not xsd:
if xml_file.upper().find('BVD') != -1: # TODO костыль для автомата
for file in os.listdir(os.getcwd()):
if file.endswith(".xsd"):
if file.upper().find('BVD') != -1:
self.load_xsd_from_path(os.path.join(os.getcwd(), file))
elif xml_file.upper().find('BVS') != -1: # TODO костыль для автомата
for file in os.listdir(os.getcwd()):
if file.endswith(".xsd"):
if file.upper().find('BVS') != -1:
self.load_xsd_from_path(os.path.join(os.getcwd(), file))
elif xml_file.upper().find('Ф310') != -1 or xml_file.upper().find('F310') != -1: # TODO костыль для автомата
for file in os.listdir(os.getcwd()):
if file.endswith(".xsd"):
if file.upper().find('Ф310') != -1:
self.load_xsd_from_path(os.path.join(os.getcwd(), file))
else:
messagebox.showerror("Error", "XSD invalid or not found")
self.lbl_val_result.config(text = "False", fg="#fc0335")
return
xml = lxml.etree.parse(xml_file)
xsd = lxml.etree.XMLSchema(file=xsd_file)
is_valid = xsd.validate(xml)
if is_valid:
self.lbl_val_result.config(text = "True", fg="#03fc07")
else:
self.lbl_val_result.config(text = "False", fg="#fc0335")
self.lbl_val_log.insert('end', xsd.error_log)
if self.notepad.get():
with open('log.txt', "w") as f:
f.writelines(str(xsd.error_log))
f.close()
webbrowser.open("log.txt")
if xml_file.upper().find('BVD') != -1: # TODO костыль для автомата
for file in os.listdir(os.getcwd()):
if file.endswith(".xsd"):
if file.upper().find('BVD') != -1:
self.load_xsd_from_path(os.path.join(os.getcwd(), file))
elif xml_file.upper().find('BVS') != -1: # TODO костыль для автомата
for file in os.listdir(os.getcwd()):
if file.endswith(".xsd"):
if file.upper().find('BVS') != -1:
self.load_xsd_from_path(os.path.join(os.getcwd(), file))
elif xml_file.upper().find('Ф310') != -1 or xml_file.upper().find('F310') != -1: # TODO костыль для автомата
for file in os.listdir(os.getcwd()):
if file.endswith(".xsd"):
if file.upper().find('Ф310') != -1:
self.load_xsd_from_path(os.path.join(os.getcwd(), file))
else:
# messagebox.showerror("Error", "XSD not found")
# self.lbl_val_result.config(text = "False", fg="#fc0335")
return
xml = lxml.etree.parse(xml_file)
xsd = lxml.etree.XMLSchema(file=xsd_file)
is_valid = xsd.validate(xml)
if is_valid:
self.lbl_val_result.config(text = "True", fg="#03fc07")
else:
self.lbl_val_result.config(text = "False", fg="#fc0335")
self.lbl_val_log.insert('end', xsd.error_log)
if self.notepad.get():
with open('log.txt', "w") as f:
f.writelines(str(xsd.error_log))
f.close()
webbrowser.open("log.txt")
def __init__(self, *args, **kwargs):
tk.Frame.__init__(self, *args, **kwargs)
self.bghex = '#ffffff'
self.btnhex = '#edf4f5'
self.config(bg=self.bghex)
self.i1frame = tk.Frame(self)
self.i1frame.config(bg=self.bghex)
self.btn_xml = tk.Button(self.i1frame, text='Choose XML', font=("Arial", 15), command=self.load_xml)
self.lbl_xml = tk.Label(self.i1frame, text="Empty", font=("Arial", 15))
self.btn_xml.config(bg=self.btnhex)
self.lbl_xml.config(bg=self.bghex)
self.btn_xml.pack(side="left", fill='both', expand=False)
self.lbl_xml.pack(side="right", fill='both', expand=False)
self.i2frame = tk.Frame(self)
self.i2frame.config(bg=self.bghex)
self.btn_xsd = tk.Button(self.i2frame, text='Choose XSD', font=("Arial", 15), command=self.load_xsd)
self.lbl_xsd = tk.Label(self.i2frame, text="Empty", font=("Arial", 15))
self.btn_xsd.config(bg=self.btnhex)
self.lbl_xsd.config(bg=self.bghex)
self.btn_xsd.pack(side="left", fill=None, expand=False)
self.lbl_xsd.pack(side="right", fill=None, expand=False)
self.i3frame = tk.Frame(self)
self.i3frame.config(bg=self.bghex)
self.btn_validate = tk.Button(self.i3frame, text='Validate', font=("Arial", 15), command=self.validate)
self.notepad = tk.BooleanVar()
self.notepad.set(0)
self.check_box_notepad = tk.Checkbutton(self.i3frame, text="Notepad",
variable=self.notepad,
onvalue=1, offvalue=0)
self.auto = tk.BooleanVar()
self.auto.set(0)
self.check_box_auto = tk.Checkbutton(self.i3frame, text="Auto XSD",
variable=self.auto,
onvalue=1, offvalue=0)
self.btn_validate.config(bg=self.btnhex)
self.check_box_notepad.config(bg=self.bghex)
self.check_box_auto.config(bg=self.bghex)
self.btn_validate.pack(side="left", fill=None, expand=False)
self.check_box_notepad.pack(side="right", fill=None, expand=False)
self.check_box_auto.pack(side="right", fill=None, expand=False)
self.i4frame = tk.Frame(self)
self.i4frame.config(bg=self.bghex)
self.lbl_val_label = tk.Label(self.i4frame, text="Result: ", font=("Arial", 15))
self.lbl_val_result = tk.Label(self.i4frame, text="", font=("Arial", 15))
self.lbl_val_label.config(bg=self.bghex)
self.lbl_val_result.config(bg=self.bghex)
self.lbl_val_label.pack(side="left", fill=None, expand=False)
self.lbl_val_result.pack(side="right", fill=None, expand=False)
self.lbl_val_log = ScrolledText(self,
wrap = tk.WORD,
# state ='disabled', i not found way to make ScrolledText readonly
width = 63,
height = 20,
font = ("Times New Roman",
15))
self.i1frame.grid(row=1, column=1, sticky="w")
self.i2frame.grid(row=2, column=1, sticky="w")
self.i3frame.grid(row=3, column=1, sticky="w")
self.i4frame.grid(row=4, column=1, sticky="w")
self.lbl_val_log.grid(row=5, column=1, sticky="w")
self.grid_columnconfigure(1, weight=1)
if __name__ == "__main__":
root = tk.Tk()
root.title('XSD tool')
view = ToolView(root)
view.pack(side="top", fill="both", expand=True)
root.wm_geometry("650x600")
root.mainloop()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment