Я пробовал все виды логики и методов и даже искал много, но все же не мог придумать удовлетворительного ответа на вопрос, который у меня есть. Я написал программу, как показано ниже, чтобы выделить конкретный xml-код, где я столкнулся с некоторыми проблемами. Извините за то, что этот пост немного длинный. Я только хотел четко объяснить свою проблему.Выделите различия между двумя файлами xml в текстовом поле Tkinter
EDIT: Для запуска ниже данной программы вам потребуется два XML-файлы, которые являются здесь: sample1 и sample2. Сохраните эти файлы и в поле ниже кода отредактируйте местоположение, где вы хотите сохранить ваши файлы в C:/Users/editThisLocation/Desktop/sample1.xml
from lxml import etree
from collections import defaultdict
from collections import OrderedDict
from distutils.filelist import findall
from lxml._elementpath import findtext
from Tkinter import *
import Tkinter as tk
import ttk
root = Tk()
class CustomText(tk.Text):
def __init__(self, *args, **kwargs):
tk.Text.__init__(self, *args, **kwargs)
def highlight_pattern(self, pattern, tag, start, end,
regexp=True):
start = self.index(start)
end = self.index(end)
self.mark_set("matchStart", start)
self.mark_set("matchEnd", start)
self.mark_set("searchLimit", end)
count = tk.IntVar()
while True:
index = self.search(pattern, "matchEnd","searchLimit",
count=count, regexp=regexp)
if index == "": break
self.mark_set("matchStart", index)
self.mark_set("matchEnd", "%s+%sc" % (index, count.get()))
self.tag_add(tag, "matchStart", "matchEnd")
def Remove_pattern(self, pattern, tag, start="1.0", end="end",
regexp=True):
start = self.index(start)
end = self.index(end)
self.mark_set("matchStart", start)
self.mark_set("matchEnd", start)
self.mark_set("searchLimit", end)
count = tk.IntVar()
while True:
index = self.search(pattern, "matchEnd","searchLimit",
count=count, regexp=regexp)
if index == "": break
self.mark_set("matchStart", index)
self.mark_set("matchEnd", "%s+%sc" % (index, count.get()))
self.tag_remove(tag, start, end)
recovering_parser = etree.XMLParser(recover=True)
sample1File = open('C:/Users/editThisLocation/Desktop/sample1.xml', 'r')
contents_sample1 = sample1File.read()
sample2File = open('C:/Users/editThisLocation/Desktop/sample2.xml', 'r')
contents_sample2 = sample2File.read()
frame1 = Frame(width=768, height=25, bg="#000000", colormap="new")
frame1.pack()
Label(frame1, text="sample 1 below - scroll to see more").pack()
textbox = CustomText(root)
textbox.insert(END,contents_sample1)
textbox.pack(expand=1, fill=BOTH)
frame2 = Frame(width=768, height=25, bg="#000000", colormap="new")
frame2.pack()
Label(frame2, text="sample 2 below - scroll to see more").pack()
textbox1 = CustomText(root)
textbox1.insert(END,contents_sample2)
textbox1.pack(expand=1, fill=BOTH)
sample1 = etree.parse("C:/Users/editThisLocation/Desktop/sample1.xml", parser=recovering_parser).getroot()
sample2 = etree.parse("C:/Users/editThisLocation/Desktop/sample2.xml", parser=recovering_parser).getroot()
ToStringsample1 = etree.tostring(sample1)
sample1String = etree.fromstring(ToStringsample1, parser=recovering_parser)
ToStringsample2 = etree.tostring(sample2)
sample2String = etree.fromstring(ToStringsample2, parser=recovering_parser)
timesample1 = sample1String.findall('{http://www.example.org/eHorizon}time')
timesample2 = sample2String.findall('{http://www.example.org/eHorizon}time')
for i,j in zip(timesample1,timesample2):
for k,l in zip(i.findall("{http://www.example.org/eHorizon}feature"), j.findall("{http://www.example.org/eHorizon}feature")):
if [k.attrib.get('color'), k.attrib.get('type')] != [l.attrib.get('color'), l.attrib.get('type')]:
faultyLine = [k.attrib.get('color'), k.attrib.get('type'), k.text]
def high(event):
textbox.tag_configure("yellow", background="yellow")
limit_1 = '<p1:time nTimestamp="{0}">'.format(5) #limit my search between timestamp 5 and timestamp 6
limit_2 = '<p1:time nTimestamp="{0}">'.format((5+1)) # timestamp 6
highlightString = '<p1:feature color="{0}" type="{1}">{2}</p1:feature>'.format(faultyLine[0],faultyLine[1],faultyLine[2]) #string to be highlighted
textbox.highlight_pattern(limit_1, "yellow", start=textbox.search(limit_1, '1.0', stopindex=END), end=textbox.search(limit_2, '1.0', stopindex=END))
textbox.highlight_pattern(highlightString, "yellow", start=textbox.search(limit_1, '1.0', stopindex=END), end=textbox.search(limit_2, '1.0', stopindex=END))
button = 'press here to highlight error line'
c = ttk.Label(root, text=button)
c.bind("<Button-1>",high)
c.pack()
root.mainloop()
То, что я хочу
Если вы работаете над кодом, было бы представить выход ниже:
Как вы можете видеть на картинке, я только собираюсь, чтобы выделить код, помеченный с зеленой галочкой. Некоторые из вас могут подумать о том, чтобы ограничить начальный и конечный индексы, чтобы выделить этот шаблон. Однако, если вы видите в моей программе, я уже использую начальные и конечные индексы для ограничения моего вывода только nTimestamp="5"
, и для этого я использую переменные limit_1
и limit_2
.
Итак, в этом типе данных, как правильно выделить один шаблон из многих внутри отдельных nTimestamp
?
EDIT: Здесь я специально хочу выделить 3-й пункт в nTimestamp="5"
, потому что этот элемент не присутствует в sample2.xml
, как вы можете увидеть в двух XML-файлов и при запуске программы она также отличает это. Единственная проблема заключается в том, чтобы выделить правильный элемент, который является третьим в моем случае.
Я использую класс подсветки из кода Bryan Oakley в here
EDIT Последние
В контексте к тому, что kobejohn спросил ниже в комментариях, целевой файл никогда не будет пустым. Всегда есть вероятность, что целевой файл может иметь дополнительные или отсутствующие элементы. Наконец, мое намерение состоит в том, чтобы выделить только глубокие элементы, которые отличаются или отсутствуют, и timestamps
, в котором они расположены. Однако выделение timestamps
выполняется правильно, но проблема выделения глубоких элементов, как описано выше, по-прежнему остается проблемой. Спасибо kobejohn для уточнения это.
Примечание:
Один метод, который я знаю, и вы могли бы предположить, что работает правильно, чтобы извлечь индекс зеленого цвета галочкой шаблон и просто запустить выделите тег над ним, но этот подход очень жестко и в больших данных, где вам приходится иметь дело с множеством вариаций, он совершенно неэффективен. Я ищу еще один лучший вариант.
Это здорово, что вы включили полностью функционирующий код и желаемый фактический вывод. Однако мне сложно понять вашу логику. Не могли бы вы объяснить шаг за шагом, как вы хотите выделить текст для выделения? – KobeJohn
Да, конечно, и я прошу прощения за поздний ответ. Текст, который я хочу выделить, состоит из цельной строки в виде строки. Напр. в вышеприведенном коде эта строка определяется в переменной 'highlightString'. Теперь возникает задача идентифицировать из всех элементов 3 'location', которые будут выделены экземпляром' highlightString', поскольку во всех трех элементах местоположения есть одни и те же строки. Поэтому в приведенном выше случае я намерен выделить строку, расположенную в третьем элементе 'location' в' nTimestamp = "5" ' – Dhruvify
Я также добавил еще несколько комментариев к моему коду, которые могут сделать ваше понимание более ясным. – Dhruvify