Viewer.XML_Edit のソースコード

"""
XMLファイルを閲覧・編集するためのTkinterアプリケーションを提供します。

このスクリプトは、指定されたXMLファイルをGUIで表示し、
ユーザーが内容を編集して保存できる機能を提供します。
VASPのvasprun.xmlのような構造化されたXMLファイルの視覚的な確認や修正に適しています。

:doc:`XML_Edit_usage`
"""
import sys
import tkinter as tk
from tkinter import ttk, messagebox
import xml.etree.ElementTree as ET


file_path = '../XML/vasprun.xml'
window_size = '800x600'

nargs = len(sys.argv)
if nargs >= 2:
    file_path = sys.argv[1]
if nargs >= 3:
    window_size = sys.argv[2]


[ドキュメント] class XMLViewerEditor: """ XMLファイルをGUIで表示し、編集機能を提供するアプリケーションクラスです。 Tkinterを使用してXMLドキュメントのツリー構造を表示し、 ユーザーがその内容をテキストエリアで直接編集し、変更を適用できるようにします。 """ def __init__(self, root, file_path, window_size): """ XMLViewerEditorクラスの新しいインスタンスを初期化します。 GUIのルートウィンドウ、Treeview、テキストエディタ、およびボタンを設定し、 指定されたXMLファイルをロードして表示します。 :param root: Tkinterアプリケーションのルートウィンドウインスタンス。 :type root: tk.Tk :param file_path: ロードするXMLファイルのパス。 :type file_path: str :param window_size: GUIウィンドウの初期サイズ(例: '800x600')。 :type window_size: str """ self.root = root self.root.title("XML Viewer and Editor") self.root.geometry(window_size) self.tree = ttk.Treeview(self.root) self.tree.heading('#0', text='Element') self.tree.pack(fill='both', expand=True) self.load_xml(file_path) self.text_editor = tk.Text(self.root, wrap="none") self.text_editor.pack(fill="both", expand=True) self.text_editor.grid_remove() self.edit_button = tk.Button(self.root, text="Edit XML", command=self.toggle_edit_mode) self.edit_button.pack()
[ドキュメント] def load_xml(self, file_path): """ 指定されたXMLファイルを解析し、Treeviewに表示するための準備を行います。 ファイルが見つからない、またはXMLとして不正な場合にエラーメッセージを表示します。 :param file_path: ロードするXMLファイルのパス。 :type file_path: str """ try: tree = ET.parse(file_path) self.root_element = tree.getroot() self.tree.delete(*self.tree.get_children()) # 既存のTreeviewの内容をクリア self.display_element(self.root_element, "") except ET.ParseError as e: messagebox.showerror("Error", f"XMLファイルの解析エラー: {e}") except FileNotFoundError: messagebox.showerror("Error", f"ファイルが見つかりません: {file_path}") except Exception as e: messagebox.showerror("Error", f"予期せぬエラーが発生しました: {e}")
[ドキュメント] def display_element(self, element, parent_id): """ XML要素とその子要素を再帰的にTreeviewウィジェットに表示します。 要素のタグと属性がTreeviewのアイテムとして挿入されます。 :param element: 表示するXML要素オブジェクト。 :type element: xml.etree.ElementTree.Element :param parent_id: Treeview内で現在の要素の親となるアイテムのID。 :type parent_id: str """ item = self.tree.insert(parent_id, "end", text=element.tag) for key, value in element.attrib.items(): self.tree.insert(item, "end", text=f"{key}: {value}") if element.text and element.text.strip(): self.tree.insert(item, "end", text=f"Text: {element.text.strip()}") for child in element: self.display_element(child, item)
[ドキュメント] def toggle_edit_mode(self): """ XML表示モードと編集モードを切り替えます。 現在編集モードの場合、テキストエディタの内容を解析してXMLツリーを更新し、 表示モードに戻ります。XMLが不正な場合はエラーを表示します。 現在表示モードの場合、現在のXMLツリーを文字列としてテキストエディタに表示し、 編集モードに切り替えます。 ボタンのテキストも適宜「Edit XML」と「Save XML」に切り替わります。 """ if self.text_editor.winfo_viewable(): # 編集モードから表示モードへ切り替え edited_xml = self.text_editor.get("1.0", "end-1c") # 最後の改行文字を除外 try: new_root = ET.fromstring(edited_xml) self.root_element = new_root self.tree.delete(*self.tree.get_children()) self.display_element(self.root_element, "") self.text_editor.grid_remove() self.edit_button.config(text="Edit XML") except ET.ParseError as e: messagebox.showerror("Error", f"XML形式が不正です: {e}") else: # 表示モードから編集モードへ切り替え # Pretty printにする場合は ET.tostring() に encoding='unicode', pretty_print=True を指定 # しかし、ElementTreeのtostringにはpretty_print引数はないため、手動で整形するか別のライブラリを使う # ここでは元のコードの挙動を維持し、整形せずにそのまま表示する xml_string = ET.tostring(self.root_element, encoding='utf-8').decode('utf-8') self.text_editor.delete("1.0", "end") self.text_editor.insert("1.0", xml_string) self.text_editor.grid() self.edit_button.config(text="Save XML")
if __name__ == "__main__": root = tk.Tk() app = XMLViewerEditor(root, file_path, window_size) root.mainloop()