Zig
Zig
PDF Update or Add XML Metadata
Demonstrates how to add or update the XML metadata stored in a PDF.Note: This example requires Chilkat v10.1.0 or later.
Chilkat Zig Downloads
const std = @import("std");
const chilkat = @import("chilkat");
pub fn main(init: std.process.Init) !void {
const alloc = init.arena.allocator();
// This requires the Chilkat API to have been previously unlocked.
// See Global Unlock Sample for sample code.
const pdf = try chilkat.Pdf.init();
defer pdf.deinit();
// Load a PDF file.
// If the PDF file already has metadata, we'll update it.
// Otherwise this example adds the metadata.
pdf.loadFile("qa_data/pdf/blank_with_metadata.pdf") catch {
std.debug.print("{s}\n", .{try pdf.getLastErrorText(alloc)});
return;
};
const xml = try chilkat.Xml.init();
defer xml.deinit();
const sb_existing = try chilkat.StringBuilder.init();
defer sb_existing.deinit();
if (pdf.getMetadata(sb_existing)) {
xml.loadSb(sb_existing, true) catch {};
} else |_| {
// Otherwise create the bare minimum XMP metadata.
xml.setTag("x:xmpmeta");
xml.addAttribute("xmlns:x", "adobe:ns:meta/") catch {};
xml.addAttribute("x:xmptk", "Adobe XMP Core 9.1-c001 79.675d0f7, 2023/06/11-19:21:16 ") catch {};
xml.updateAttrAt("rdf:RDF", true, "xmlns:rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#") catch {};
xml.updateAttrAt("rdf:RDF|rdf:Description", true, "rdf:about", "") catch {};
xml.updateAttrAt("rdf:RDF|rdf:Description", true, "xmlns:xmp", "http://ns.adobe.com/xap/1.0/") catch {};
xml.updateAttrAt("rdf:RDF|rdf:Description", true, "xmlns:dc", "http://purl.org/dc/elements/1.1/") catch {};
xml.updateAttrAt("rdf:RDF|rdf:Description", true, "xmlns:xmpMM", "http://ns.adobe.com/xap/1.0/mm/") catch {};
xml.updateAttrAt("rdf:RDF|rdf:Description", true, "xmlns:pdf", "http://ns.adobe.com/pdf/1.3/") catch {};
xml.updateAttrAt("rdf:RDF|rdf:Description", true, "xmlns:xmpRights", "http://ns.adobe.com/xap/1.0/rights/") catch {};
const dt = try chilkat.DateTime.init();
defer dt.deinit();
dt.setFromCurrentSystemTime() catch {};
const ts = try dt.getAsTimestamp(alloc, true);
xml.updateChildContent("rdf:RDF|rdf:Description|xmp:ModifyDate", ts);
xml.updateChildContent("rdf:RDF|rdf:Description|xmp:CreateDate", ts);
xml.updateChildContent("rdf:RDF|rdf:Description|xmp:MetadataDate", ts);
xml.updateChildContent("rdf:RDF|rdf:Description|xmp:CreatorTool", "My Custom Application");
xml.updateChildContent("rdf:RDF|rdf:Description|dc:format", "application/pdf");
const sb_doc_id = try chilkat.StringBuilder.init();
defer sb_doc_id.deinit();
sb_doc_id.append("uuid:") catch {};
sb_doc_id.appendUuid(true) catch {};
xml.updateChildContent("rdf:RDF|rdf:Description|xmpMM:DocumentID", try sb_doc_id.getAsString(alloc));
const sb_instance_id = try chilkat.StringBuilder.init();
defer sb_instance_id.deinit();
sb_instance_id.append("uuid:") catch {};
sb_instance_id.appendUuid(true) catch {};
xml.updateChildContent("rdf:RDF|rdf:Description|xmpMM:InstanceID", try sb_instance_id.getAsString(alloc));
}
// Add our custom metadata tags to either the existing XML metdata, or the newly created metadata.
xml.updateAttrAt("rdf:RDF|rdf:Description", true, "xmlns:zf", "urn:ferd:pdfa:CrossIndustryDocument:invoice:1p0#") catch {};
xml.updateAttrAt("rdf:RDF|rdf:Description", true, "rdf:about", " ") catch {};
xml.updateChildContent("rdf:RDF|rdf:Description|zf:ConformanceLevel", "BASIC");
xml.updateChildContent("rdf:RDF|rdf:Description|zf:DocumentFileName", "ZZZZZZ-invoice.xml");
xml.updateChildContent("rdf:RDF|rdf:Description|zf:DocumentType", "INVOICE");
xml.updateChildContent("rdf:RDF|rdf:Description|zf:Version", "1.0");
// Create a new PDF with the updated metadata.
const sb = try chilkat.StringBuilder.init();
defer sb.deinit();
xml.getXmlSb(sb) catch {};
if (pdf.updateMetadata(sb, "c:/temp/qa_output/out.pdf")) {
std.debug.print("Success\n", .{});
} else |_| {
std.debug.print("{s}\n", .{try pdf.getLastErrorText(alloc)});
}
// To see the metadata in Adobe Acrobat DC,
// 1) Open the PDF.
// 2) CTRL-D to show the Document Properties dialog.
// 3) In the dialog, click on the "Additional Metadata" button.
// 4) In the Additional Data dialog, click on "Advanced"
// 5) Expand the namespace tree for the metadata you added.
std.debug.print("OK\n", .{});
}