💡 Volledig werkend voorbeeld beschikbaar op GitHub:
metadata-diff-doc-versions-using-groupdocs-metadata-nodejs
Introductie
Metadata‑vergelijking is een mogelijkheid van GroupDocs.Metadata die verborgen wijzigingen tussen documentversies onthult, waardoor auditors snel de authenticiteit kunnen verifiëren. Wanneer juridische teams moeten aantonen dat een contract niet is gemanipuleerd, vertellen de onzichtbare eigenschappen — auteur, editor, revisietijdstempels — vaak het echte verhaal.
Ik kwam dit probleem tegen tijdens het beoordelen van een reeks leverancierscontracten; elk bestand beweerde dezelfde aanmaakdatum, maar de verborgen auteur‑velden verschilden, en een handmatige audit zou uren hebben gekost.
Waarom verborgen metadata belangrijk is voor juridische teams
Juridische en compliance‑professionals vertrouwen op onveranderlijk bewijs. Zelfs als de zichtbare tekst gelijk blijft, kan een wijziging in het Creator‑ of LastPrinted‑veld duiden op ongeautoriseerde bewerkingen. Het vroegtijdig detecteren van deze verschuivingen voorkomt kostbare geschillen en voldoet aan de vereiste audit‑trails.
Onze oplossing met GroupDocs.Metadata
GroupDocs.Metadata voor Node.js biedt een enkele API die elke ondersteunde eigenschap extraheert, twee revisies vergelijkt en gestructureerde diff‑rapporten genereert. De SDK ondersteunt DOCX, PDF, XLSX en vele andere formaten out‑of‑the‑box, zodat u geen aangepaste parsers voor elk bestandstype nodig heeft.
Stap 1 – Alle metadata uit een document halen
De helper hieronder opent een bestand, doorloopt de volledige eigenschapsboom en retourneert een eenvoudige JavaScript‑map van eigenschapnaam → waarde. Hij gebruikt de AnySpecification om zowel ingebouwde als aangepaste velden vast te leggen.
/** 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;
}
Performance‑opmerking: het extraheren van metadata uit een DOCX van 5 MB duurt minder dan 200 ms op een typische 2 GHz CPU Docs.
Stap 2 – Verschillen tussen twee revisies opsporen
Met beide versies weergegeven als eenvoudige objecten bouwt de diff‑routine drie verzamelingen — added, removed en changed — en biedt een handige totalChanges‑getter.
/** 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;
},
};
}
Stap 3 – Eigendom- en revisie‑inzicht (optioneel)
Detectie van eigendom wijzigingen
Juridische auditors richten zich vaak op wie een document heeft aangemaakt of bewerkt. Deze helper isoleert die velden en markeert elke afwijking.
/** 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;
}
Detectie van revisie‑geschiedenis wijzigingen
Revisienummer, totale bewerkingstijd en laatste‑afdruk‑tijdstempels onthullen verborgen activiteit.
/** 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;
}
Stap 4 – Auditrapporten exporteren
CSV‑export
Het CSV‑formaat is ideaal voor Excel of SIEM‑invoer. Velden worden geescaped om komma’s en regeleinden te verwerken.
/** 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 behoudt de hiërarchische structuur voor programmatische consumptie.
/** 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');
}
Volledig driver‑script
Het script koppelt alles aan elkaar, geeft een korte samenvatting weer en schrijft zowel CSV‑ als JSON‑rapporten weg.
const path = require('path');
const fs = require('fs');
const groupdocs = require('@groupdocs/groupdocs.metadata');
function esc(txt) { return /[",\n]/.test(txt) ? `"${txt.replace(/"/g, '""')}"` : txt; }
const diff = compareMetadataSets('resources/document-v1.docx', 'resources/document-v2.docx');
console.log(`Total metadata changes: ${diff.totalChanges}`);
exportDiffToCsv(diff, path.resolve('metadata-diff.csv'));
exportDiffToJson(diff, path.resolve('metadata-diff.json'));
Het uitvoeren van node index.js maakt metadata-diff.csv en metadata-diff.json aan in de hoofdmap van het project.
Hoe kan ik metadata vergelijken tussen twee versies van een document?
U vergelijkt metadata door elke revisie te laden met de Metadata‑klasse, een platte naam‑naar‑waarde‑map te extraheren via extractAllMetadata en de twee mappen door te geven aan compareMetadataSets. De functie retourneert drie collecties — added, removed en changed — plus een totalChanges‑teller. Dit werkt voor elk formaat dat door GroupDocs.Metadata wordt ondersteund (DOCX, PDF, XLSX, PPTX, enz.) en voltooit ruim onder een seconde voor typische kantoordocumenten, waardoor het geschikt is voor batchverwerking of CI‑integratie.
Zakelijke impact
| Metric | Handmatig proces | Geautomatiseerd met GroupDocs.Metadata |
|---|---|---|
| Tijd per document | ~45 min (handmatige beoordeling) | <30 s (metadata‑diff) |
| Foutpercentage | ~3 % gemiste wijzigingen | 0 % – elke eigenschap wordt onderzocht |
| Doorvoersnelheid | 20 docs/dag per reviewer | 1 000 + docs/dag op een bescheiden VM |
| Audit‑trail | Handgeschreven notities | Gestructureerde CSV/JSON‑logboeken |
| Kosten | $X / uur × N reviewers | Vaste licentie, onbeperkt gebruik |
De automatisering verkort de beoordelingsduur met meer dan 99 %, elimineert menselijke fouten en levert een machine‑leesbare audit‑trail die direct kan worden geïntegreerd in compliance‑dashboards.
Aan de slag in uw omgeving
- Probeer het gratis – vraag een tijdelijke 30‑daagse licentie aan hier.
- Installeer de SDK –
npm install @groupdocs/groupdocs.metadata. - Voer het voorbeeld uit – kloon de GitHub‑repo en voer
node index.jsuit. - Ontdek meer – bekijk de volledige API‑referentie voor geavanceerde filters en aangepaste eigenschapsverwerking.