Implementiert automatische Erkennung von XML-Datei-Duplikaten basierend auf blake2b-Hashes. Bei Hash-Match wird die vorhandene Datei automatisch zugeordnet statt sie zu kopieren. Bei Dateinamen-Konflikten werden alternative Namen (datei_1.xml, datei_2.xml, etc.) mit Auswahl-Dialog angeboten. Neue Features: - Projekt-weite Hash-Duplikatserkennung - Automatische Zuordnung vorhandener Dateien bei Hash-Match - Alternative Dateinamen-Generierung mit Benutzer-Dialog - Performance-Optimierung durch Set-basierte Dateinamen-Prüfung - Umfassende Dokumentation und Test-Suite 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
11 KiB
XML-Hash-Duplikatserkennung und intelligente Dateinamen-Verwaltung
Übersicht
Diese Dokumentation beschreibt die erweiterte Funktionalität zur Hash-basierten Duplikatserkennung von XML-Dateien und intelligenten Dateinamen-Verwaltung in der XSL-Validator-Anwendung.
Neue Funktionalitäten
1. Hash-basierte Duplikatserkennung
Beim Hinzufügen neuer XML-Dateien wird automatisch geprüft, ob bereits eine Datei mit identischem Inhalt (basierend auf blake2b-Hash) im Projekt vorhanden ist.
Vorteile:
- Vermeidung von Datei-Duplikaten
- Automatische Zuordnung vorhandener Dateien
- Speicherplatz-Optimierung
- Konsistente Datenintegrität
2. Intelligente Dateinamen-Verwaltung
Bei Dateinamen-Konflikten werden automatisch alternative Namen im Format datei_1.xml, datei_2.xml, etc. generiert.
Features:
- Automatische Generierung alternativer Dateinamen
- Benutzerfreundlicher Auswahl-Dialog
- Vermeidung von Überschreibungen
- Konsistente Namenskonventionen
3. Nahtlose Integration
Die neuen Funktionalitäten sind vollständig in bestehende Workflows integriert:
- Drag & Drop: Automatische Hash-Prüfung beim Ziehen von XML-Dateien
- Kontextmenü: Hash-Prüfung beim manuellen Hinzufügen über "XML-Datei hinzufügen"
Technische Implementierung
Kern-Architektur
def _assign_xml_to_xsl_nodes(self, xml_file_path: Path, selected_xsl_nodes: list):
# 1. Hash berechnen
file_hash = self._calculate_hash_for_file(xml_file_path)
# 2. Duplikatsprüfung
existing_xml = self._find_xml_file_by_hash(file_hash)
if existing_xml:
# 3. Automatische Zuordnung bei Hash-Match
self._assign_existing_xml_to_nodes(existing_xml, selected_xsl_nodes)
else:
# 4. Neue Datei verarbeiten
self._process_new_xml_file(xml_file_path, selected_xsl_nodes, file_hash)
Neue Hilfsmethoden
Hash-Vergleich und Suche
def _get_all_project_xml_files(self) -> List[XmlFile]:
"""Sammelt alle XML-Dateien aus dem gesamten Projekt."""
def _find_xml_file_by_hash(self, target_hash: str) -> XmlFile | None:
"""Sucht XML-Datei mit spezifischem Hash im Projekt."""
def _calculate_hash_for_file(self, file_path: Path) -> str | None:
"""Berechnet blake2b-Hash für eine Datei."""
Dateinamen-Verwaltung
def _generate_alternative_filename(self, original_path: Path, xml_dir: Path) -> Path:
"""Generiert alternative Dateinamen im Format: datei_1.xml, datei_2.xml, ..."""
def _is_filename_used_in_project(self, relative_xml_path: Path) -> bool:
"""Prüft ob Dateiname bereits im Projekt verwendet wird."""
def _show_filename_selection_dialog(self, original_name: str, alternative_paths: List[Path]) -> Path | None:
"""Zeigt Dialog zur Auswahl alternativer Dateinamen."""
Verarbeitungslogik
def _assign_existing_xml_to_nodes(self, existing_xml: XmlFile, selected_xsl_nodes: list):
"""Ordnet vorhandene XML-Datei (Hash-Match) den XSL-Knoten zu."""
def _process_new_xml_file(self, xml_file_path: Path, selected_xsl_nodes: list, file_hash: str | None):
"""Verarbeitet neue XML-Datei (kein Hash-Match)."""
Benutzer-Workflows
Workflow 1: Hash-Duplikat gefunden
- Benutzer fügt XML-Datei hinzu (Drag&Drop oder Kontextmenü)
- System berechnet Hash der neuen Datei
- Hash-Match mit vorhandener Datei gefunden
- Automatische Zuordnung: Vorhandene Datei wird den ausgewählten XSL-Knoten zugeordnet
- Erfolgsmeldung: "XML-Datei mit gleichem Inhalt bereits vorhanden - automatisch zugeordnet"
Workflow 2: Neue Datei, Dateiname-Konflikt
- Benutzer fügt XML-Datei hinzu
- Kein Hash-Match gefunden (neue Datei)
- Dateiname bereits vorhanden
- Dialog angezeigt: Auswahl alternativer Dateinamen
- Benutzer wählt gewünschten Namen
- Datei wird kopiert und zugeordnet
- Erfolgsmeldung mit Hinweis auf Umbenennung
Workflow 3: Neue Datei, kein Konflikt
- Benutzer fügt XML-Datei hinzu
- Kein Hash-Match gefunden
- Dateiname verfügbar
- Direkte Verarbeitung: Datei wird kopiert und zugeordnet
- Standard-Erfolgsmeldung
Benutzeroberfläche
Hash-Duplikat Dialog
┌─────────────────────────────────────────┐
│ XML-Datei zugeordnet │
├─────────────────────────────────────────┤
│ Eine XML-Datei mit gleichem Inhalt war │
│ bereits im Projekt vorhanden. │
│ │
│ Die vorhandene Datei 'dokument.xml' │
│ wurde automatisch zu 2 XSL-Knoten │
│ zugeordnet. │
├─────────────────────────────────────────┤
│ [OK] │
└─────────────────────────────────────────┘
Dateiname-Auswahl Dialog
┌─────────────────────────────────────────┐
│ Dateiname auswählen │
├─────────────────────────────────────────┤
│ Eine Datei mit dem Namen 'test.xml' │
│ existiert bereits. │
│ │
│ Bitte wählen Sie einen alternativen │
│ Dateinamen: │
│ │
│ ○ test_1.xml │
│ ● test_2.xml │
│ ○ test_3.xml │
│ ○ test_4.xml │
├─────────────────────────────────────────┤
│ [OK] [Abbrechen] │
└─────────────────────────────────────────┘
Performance-Optimierungen
Hash-Berechnung
- Synchrone Berechnung für neue Dateien (akzeptable Verzögerung)
- Effiziente blake2b-Implementierung aus Python's hashlib
- Caching von Hash-Werten in XmlFile-Objekten
Projekt-weite Suche
- Einmalige Sammlung aller XML-Dateien pro Operation
- Optimierte Rekursion durch die Node-Struktur
- Duplikat-Vermeidung bei der Sammlung
Dateinamen-Generierung
- Sequenzielle Suche mit Sicherheitsgrenze (max. 1000 Versuche)
- Fallback-Mechanismus mit Zeitstempel
- Kombinierte Prüfung von physischer Existenz und Projekt-Verwendung
Fehlerbehandlung
Hash-Berechnung Fehler
try:
file_hash = self._calculate_hash_for_file(xml_file_path)
except Exception as e:
logger.error(f"Hash-Berechnung fehlgeschlagen: {e}")
# Fortsetzung ohne Hash (Fallback-Verhalten)
Datei-Zugriff Fehler
if not file_path.exists():
logger.warning(f"Datei nicht gefunden: {file_path}")
return None
Dialog-Fehler
try:
selected_path = self._show_filename_selection_dialog(...)
except Exception as e:
logger.error(f"Dialog-Fehler: {e}")
# Fallback: Ersten alternativen Namen verwenden
return alternative_paths[0] if alternative_paths else None
Logging
Das System verwendet strukturiertes Logging für alle Operationen:
logger.info(f"Hash-Duplikat gefunden: {existing_xml.xml} hat gleichen Hash wie {xml_file_path.name}")
logger.debug(f"Hash-Vergleich: {len(xml_files)} XML-Dateien im Projekt gefunden")
logger.warning(f"Hash-Berechnung für {xml_file_path} fehlgeschlagen")
logger.error(f"Fehler beim Zuordnen der XML-Datei: {str(e)}")
Testing
Umfassende Test-Suite
Die Implementierung wird durch eine umfassende Test-Suite validiert:
uv run python test_xml_hash_duplicate_detection.py
Test-Abdeckung:
- Hash-Berechnung und -Konsistenz
- XmlFile-Modell mit Hash-Unterstützung
- Duplikatserkennung-Logik
- Alternative Dateinamen-Generierung
- Integration Workflow
Test-Ergebnisse
=== Test: Hash-Berechnung ===
[OK] Hash-Berechnung funktioniert korrekt
=== Test: XmlFile-Modell mit Hash ===
[OK] XmlFile-Modell mit Hash funktioniert korrekt
=== Test: Duplikatserkennung-Logik ===
[OK] Duplikatserkennung-Logik funktioniert korrekt
=== Test: Alternative Dateinamen-Generierung ===
[OK] Alternative Dateinamen-Generierung funktioniert korrekt
=== Test: Integration Workflow ===
[OK] Integration Workflow funktioniert korrekt
[SUCCESS] Alle Tests erfolgreich abgeschlossen!
Kompatibilität
Rückwärtskompatibilität
- Bestehende Projekte funktionieren unverändert
- Vorhandene XML-Dateien ohne Hash werden automatisch nachberechnet
- Keine Breaking Changes in der API
Datenformat
- XmlFile.hashsum ist optional (kann None sein)
- Automatische Migration beim Projektladen
- Graceful Degradation bei Hash-Fehlern
Wartung und Erweiterung
Konfigurierbarkeit
Die Implementierung kann einfach erweitert werden:
# Verschiedene Hash-Algorithmen
def _calculate_hash(self, file_path: Path, algorithm: str = "blake2b"):
if algorithm == "blake2b":
return self._calculate_blake2b_hash(file_path)
elif algorithm == "sha256":
return self._calculate_sha256_hash(file_path)
# Konfigurierbare Dateinamen-Formate
def _generate_alternative_filename(self, original_path: Path, format_pattern: str = "{name}_{counter}{ext}"):
# Implementierung mit konfigurierbaren Mustern
Monitoring
# Performance-Metriken
start_time = time.time()
# ... Operation ...
duration = time.time() - start_time
logger.info(f"Hash-Vergleich abgeschlossen in {duration:.3f}s")
Changelog
Version 1.0.0 (2025-01-20)
- ✅ Hash-basierte Duplikatserkennung im gesamten Projekt
- ✅ Automatische Zuordnung bei Hash-Match
- ✅ Intelligente Dateinamen-Generierung (datei_1.xml Format)
- ✅ Integration in Drag&Drop und Kontextmenü
- ✅ Benutzerfreundliche Dateiname-Auswahl-Dialoge
- ✅ Umfassende Test-Suite
- ✅ Strukturiertes Logging
- ✅ Fehlerbehandlung und Fallback-Mechanismen
Fazit
Die erweiterte XML-Hash-Duplikatserkennung bietet eine robuste, benutzerfreundliche Lösung für die intelligente Verwaltung von XML-Dateien in XSL-Validator-Projekten. Die Implementierung ist vollständig getestet, performant und nahtlos in bestehende Workflows integriert.