💡 Voll funktionsfähiges Beispiel auf GitHub verfügbar:
metadata-diff-doc-versions-using-groupdocs-metadata-nodejs
Einführung
Der Metadatenvergleich ist eine Fähigkeit von GroupDocs.Metadata, die versteckte Änderungen zwischen Dokumentversionen aufdeckt und Auditoren ermöglicht, die Authentizität schnell zu überprüfen. Wenn Rechtsteams nachweisen müssen, dass ein Vertrag nicht manipuliert wurde, erzählen die unsichtbaren Eigenschaften – Autor, Bearbeiter, Zeitstempel von Revisionen – oft die wahre Geschichte.
Ich stieß auf dieses Problem, als ich einen Stapel Lieferantenverträge prüfte; jede Datei gab dasselbe Erstellungsdatum an, aber die versteckten Autorenfelder unterschieden sich, und die manuelle Prüfung hätte Stunden gedauert.
Warum versteckte Metadaten für Rechtsteams wichtig sind
Rechts- und Compliance‑Fachleute verlassen sich auf unveränderliche Beweise. Selbst wenn der sichtbare Text gleich bleibt, kann eine Änderung im Creator‑ oder LastPrinted‑Feld unautorisierte Änderungen anzeigen. Das frühzeitige Erkennen dieser Verschiebungen verhindert kostspielige Streitigkeiten und erfüllt regulatorische Prüfpfade.
Unsere Lösung mit GroupDocs.Metadata
GroupDocs.Metadata für Node.js bietet eine einheitliche API, die jede unterstützte Eigenschaft extrahiert, zwei Revisionen vergleicht und strukturierte Diff‑Berichte erzeugt. Das SDK unterstützt DOCX, PDF, XLSX und viele weitere Formate out‑of‑the‑box, sodass keine eigenen Parser für jeden Dateityp nötig sind.
Schritt 1 – Alle Metadaten aus einem Dokument extrahieren
Der untenstehende Helfer öffnet eine Datei, durchläuft den gesamten Eigenschaftsbaum und gibt eine einfache JavaScript‑Map von Eigenschaftsname → Wert zurück. Er verwendet die AnySpecification, um sowohl integrierte als auch benutzerdefinierte Felder zu erfassen.
/** Extract all metadata from a file */
function extractAllMetadata(documentPath) {
const result = {};
const metadata = new groupdocs.Metadata(documentPath);
try {
const properties = metadata.findProperties(new groupdocs.AnySpecification());
for (let i = 0; i < properties.getCount(); i++) {
const p = properties.get_Item(i);
const name = p.getName();
const value = valueToString(p);
result[name] = value;
}
} finally {
metadata.close();
}
return result;
}
Leistungshinweis: Das Extrahieren von Metadaten aus einer 5 MB DOCX dauert weniger als 200 ms auf einer typischen 2 GHz CPU [Docs][DOCS_URL].
Schritt 2 – Unterschiede zwischen zwei Revisionen erkennen
Mit beiden Versionen als einfachen Objekten erstellt die Diff‑Routine drei Buckets – added, removed und changed – und stellt einen praktischen totalChanges‑Getter bereit.
/** Compare two metadata maps */
function compareMetadataSets(pathV1, pathV2) {
const v1 = extractAllMetadata(pathV1);
const v2 = extractAllMetadata(pathV2);
const added = {};
const removed = {};
const changed = {};
for (const k of Object.keys(v2)) {
if (!(k in v1)) added[k] = v2[k];
else if (v1[k] !== v2[k]) changed[k] = { from: v1[k], to: v2[k] };
}
for (const k of Object.keys(v1)) {
if (!(k in v2)) removed[k] = v1[k];
}
return {
added,
removed,
changed,
get totalChanges() {
return Object.keys(this.added).length + Object.keys(this.removed).length + Object.keys(this.changed).length;
},
};
}
Schritt 3 – Eigentums‑ und Revisions‑Einblicke (optional)
Erkennen von Eigentumsänderungen
Rechtsprüfer konzentrieren sich häufig darauf, wer ein Dokument erstellt oder bearbeitet hat. Dieser Helfer isoliert diese Felder und markiert jede Abweichung.
/** Ownership change detection */
function detectOwnershipChanges(pathV1, pathV2) {
const v1 = readOwnership(pathV1);
const v2 = readOwnership(pathV2);
const all = new Set([...Object.keys(v1), ...Object.keys(v2)]);
const changes = {};
for (const k of all) {
const oldV = v1[k] !== undefined ? v1[k] : '<missing>';
const newV = v2[k] !== undefined ? v2[k] : '<missing>';
if (oldV !== newV) changes[k] = { from: oldV, to: newV };
}
return changes;
}
Erkennen von Änderungen in der Revisionshistorie
Revisionsnummer, gesamte Bearbeitungszeit und Zeitstempel des letzten Drucks enthüllen versteckte Aktivitäten.
/** Revision history change detection */
function detectRevisionHistory(pathV1, pathV2) {
const v1 = readRevision(pathV1);
const v2 = readRevision(pathV2);
const all = new Set([...Object.keys(v1), ...Object.keys(v2)]);
const changes = {};
for (const k of all) {
const oldV = v1[k] !== undefined ? v1[k] : '<missing>';
const newV = v2[k] !== undefined ? v2[k] : '<missing>';
if (oldV !== newV) changes[k] = { from: oldV, to: newV };
}
return changes;
}
Schritt 4 – Audit‑Berichte exportieren
CSV‑Export
Das CSV‑Format ist ideal für Excel oder SIEM‑Einspeisung. Felder werden escaped, um Kommata und Zeilenumbrüche zu handhaben.
/** Export diff to CSV */
function exportDiffToCsv(diff, outputPath) {
const rows = ['change_type,property,old_value,new_value'];
for (const [k, v] of Object.entries(diff.added)) rows.push(`added,${esc(k)},,${esc(v)}`);
for (const [k, v] of Object.entries(diff.removed)) rows.push(`removed,${esc(k)},${esc(v)},`);
for (const [k, o] of Object.entries(diff.changed)) rows.push(`changed,${esc(k)},${esc(o.from)},${esc(o.to)}`);
fs.writeFileSync(outputPath, rows.join('\n') + '\n', 'utf-8');
}
JSON‑Export
JSON bewahrt die hierarchische Struktur für die programmgesteuerte Nutzung.
/** Export diff to JSON */
function exportDiffToJson(diff, outputPath) {
const payload = { added: diff.added, removed: diff.removed, changed: diff.changed };
fs.writeFileSync(outputPath, JSON.stringify(payload, null, 2), 'utf-8');
}
Vollständiges Treiberskript
Das Skript verbindet alles, gibt