Sample code for 30+ languages & platforms
Rust

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 Rust Downloads

Rust

// This requires the Chilkat API to have been previously unlocked.
// See Global Unlock Sample for sample code.

let pdf = chilkat::Pdf::new();

// Load a PDF file.
// If the PDF file already has metadata, we'll update it.
// Otherwise this example adds the metadata.
if pdf.load_file("qa_data/pdf/blank_with_metadata.pdf").is_err() {
    println!("{}", pdf.last_error_text());
    return;
}

let xml = chilkat::Xml::new();
let sb_existing = chilkat::StringBuilder::new();

if pdf.get_metadata(&sb_existing).is_ok() {
    let _ = xml.load_sb(&sb_existing, true);
} else {

    // Otherwise create the bare minimum XMP metadata.
    xml.set_tag("x:xmpmeta");
    let _ = xml.add_attribute("xmlns:x", "adobe:ns:meta/");
    let _ = xml.add_attribute("x:xmptk", "Adobe XMP Core 9.1-c001 79.675d0f7, 2023/06/11-19:21:16 ");
    let _ = xml.update_attr_at("rdf:RDF", true, "xmlns:rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#");
    let _ = xml.update_attr_at("rdf:RDF|rdf:Description", true, "rdf:about", "");
    let _ = xml.update_attr_at("rdf:RDF|rdf:Description", true, "xmlns:xmp", "http://ns.adobe.com/xap/1.0/");
    let _ = xml.update_attr_at("rdf:RDF|rdf:Description", true, "xmlns:dc", "http://purl.org/dc/elements/1.1/");
    let _ = xml.update_attr_at("rdf:RDF|rdf:Description", true, "xmlns:xmpMM", "http://ns.adobe.com/xap/1.0/mm/");
    let _ = xml.update_attr_at("rdf:RDF|rdf:Description", true, "xmlns:pdf", "http://ns.adobe.com/pdf/1.3/");
    let _ = xml.update_attr_at("rdf:RDF|rdf:Description", true, "xmlns:xmpRights", "http://ns.adobe.com/xap/1.0/rights/");

    let dt = chilkat::DateTime::new();
    let _ = dt.set_from_current_system_time();
    let ts = dt.get_as_timestamp(true).unwrap_or_default();

    xml.update_child_content("rdf:RDF|rdf:Description|xmp:ModifyDate", &ts);
    xml.update_child_content("rdf:RDF|rdf:Description|xmp:CreateDate", &ts);
    xml.update_child_content("rdf:RDF|rdf:Description|xmp:MetadataDate", &ts);

    xml.update_child_content("rdf:RDF|rdf:Description|xmp:CreatorTool", "My Custom Application");
    xml.update_child_content("rdf:RDF|rdf:Description|dc:format", "application/pdf");

    let sb_doc_id = chilkat::StringBuilder::new();
    let _ = sb_doc_id.append("uuid:");
    let _ = sb_doc_id.append_uuid(true);
    xml.update_child_content("rdf:RDF|rdf:Description|xmpMM:DocumentID", &sb_doc_id.get_as_string().unwrap_or_default());

    let sb_instance_id = chilkat::StringBuilder::new();
    let _ = sb_instance_id.append("uuid:");
    let _ = sb_instance_id.append_uuid(true);
    xml.update_child_content("rdf:RDF|rdf:Description|xmpMM:InstanceID", &sb_instance_id.get_as_string().unwrap_or_default());

}

// Add our custom metadata tags to either the existing XML metdata, or the newly created metadata.
let _ = xml.update_attr_at("rdf:RDF|rdf:Description", true, "xmlns:zf", "urn:ferd:pdfa:CrossIndustryDocument:invoice:1p0#");
let _ = xml.update_attr_at("rdf:RDF|rdf:Description", true, "rdf:about", " ");
xml.update_child_content("rdf:RDF|rdf:Description|zf:ConformanceLevel", "BASIC");
xml.update_child_content("rdf:RDF|rdf:Description|zf:DocumentFileName", "ZZZZZZ-invoice.xml");
xml.update_child_content("rdf:RDF|rdf:Description|zf:DocumentType", "INVOICE");
xml.update_child_content("rdf:RDF|rdf:Description|zf:Version", "1.0");

// Create a new PDF with the updated metadata.
let sb = chilkat::StringBuilder::new();
let _ = xml.get_xml_sb(&sb);
if pdf.update_metadata(&sb, "c:/temp/qa_output/out.pdf").is_ok() {
    println!("Success");
} else {
    println!("{}", pdf.last_error_text());
}

// 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.

println!("OK");