Sample code for 30+ languages & platforms
Tcl

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

Tcl

load ./chilkat.dll

set success 0

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

set pdf [new_CkPdf]

# Load a PDF file.
# If the PDF file already has metadata, we'll update it.
# Otherwise this example adds the metadata.
set success [CkPdf_LoadFile $pdf "qa_data/pdf/blank_with_metadata.pdf"]
if {$success == 0} then {
    puts [CkPdf_lastErrorText $pdf]
    delete_CkPdf $pdf
    exit
}

set xml [new_CkXml]

set sbExisting [new_CkStringBuilder]

set hasMetadata [CkPdf_GetMetadata $pdf $sbExisting]
if {$hasMetadata == 1} then {
    CkXml_LoadSb $xml $sbExisting 1
} else {

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

    set dt [new_CkDateTime]

    CkDateTime_SetFromCurrentSystemTime $dt
    set ts [CkDateTime_getAsTimestamp $dt 1]

    CkXml_UpdateChildContent $xml "rdf:RDF|rdf:Description|xmp:ModifyDate" $ts
    CkXml_UpdateChildContent $xml "rdf:RDF|rdf:Description|xmp:CreateDate" $ts
    CkXml_UpdateChildContent $xml "rdf:RDF|rdf:Description|xmp:MetadataDate" $ts

    CkXml_UpdateChildContent $xml "rdf:RDF|rdf:Description|xmp:CreatorTool" "My Custom Application"
    CkXml_UpdateChildContent $xml "rdf:RDF|rdf:Description|dc:format" "application/pdf"

    set sbDocId [new_CkStringBuilder]

    CkStringBuilder_Append $sbDocId "uuid:"
    CkStringBuilder_AppendUuid $sbDocId 1
    CkXml_UpdateChildContent $xml "rdf:RDF|rdf:Description|xmpMM:DocumentID" [CkStringBuilder_getAsString $sbDocId]

    set sbInstanceId [new_CkStringBuilder]

    CkStringBuilder_Append $sbInstanceId "uuid:"
    CkStringBuilder_AppendUuid $sbInstanceId 1
    CkXml_UpdateChildContent $xml "rdf:RDF|rdf:Description|xmpMM:InstanceID" [CkStringBuilder_getAsString $sbInstanceId]

}

# Add our custom metadata tags to either the existing XML metdata, or the newly created metadata.
CkXml_UpdateAttrAt $xml "rdf:RDF|rdf:Description" 1 "xmlns:zf" "urn:ferd:pdfa:CrossIndustryDocument:invoice:1p0#"
CkXml_UpdateAttrAt $xml "rdf:RDF|rdf:Description" 1 "rdf:about" " "
CkXml_UpdateChildContent $xml "rdf:RDF|rdf:Description|zf:ConformanceLevel" "BASIC"
CkXml_UpdateChildContent $xml "rdf:RDF|rdf:Description|zf:DocumentFileName" "ZZZZZZ-invoice.xml"
CkXml_UpdateChildContent $xml "rdf:RDF|rdf:Description|zf:DocumentType" "INVOICE"
CkXml_UpdateChildContent $xml "rdf:RDF|rdf:Description|zf:Version" "1.0"

# Create a new PDF with the updated metadata.
set sb [new_CkStringBuilder]

CkXml_GetXmlSb $xml $sb
set success [CkPdf_UpdateMetadata $pdf $sb "c:/temp/qa_output/out.pdf"]
if {$success == 1} then {
    puts "Success"
} else {
    puts [CkPdf_lastErrorText $pdf]
}

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

puts "OK"

delete_CkPdf $pdf
delete_CkXml $xml
delete_CkStringBuilder $sbExisting
delete_CkDateTime $dt
delete_CkStringBuilder $sbDocId
delete_CkStringBuilder $sbInstanceId
delete_CkStringBuilder $sb