Document Metadata
Title, author, subject and keywords describe a document without opening it. PDF readers show them in the document properties, search tools index them and archives sort by them. TX Text Control writes this metadata when it saves a PDF and reads it from the PDF documents it loads. Read on for how the three settings objects work together, how to update the metadata of an existing PDF, build a keyword index, store custom properties and give an accessible PDF its title.
Setting the metadata of a new PDF with SaveSettings is shown in Create a PDF, and reading it after loading in Load and Modify a PDF.
Where Metadata Lives
Three objects carry the metadata of a document:
| Object | Role |
|---|---|
| SaveSettings | The values Save writes to the file you save now |
| LoadSettings | The values of the document that Load read; read only |
| ServerTextControl.DocumentSettings | The values of the current document: filled when a document is loaded and stored automatically when it's saved |
When you save, a value set in SaveSettings overrides the value of the same name in DocumentSettings. A property you leave empty in SaveSettings is taken from DocumentSettings, so a loaded document keeps its metadata when you save it again. The properties are:
| Metadata | SaveSettings | LoadSettings | DocumentSettings | Empty value |
|---|---|---|---|---|
| Title | DocumentTitle | DocumentTitle | DocumentTitle | Empty string |
| Author | Author | Author | Author | Empty string |
| Subject | DocumentSubject | DocumentSubject | DocumentSubject | Empty string |
| Keywords | DocumentKeywords | DocumentKeywords | DocumentKeywords | null |
| Creating application | CreatorApplication | CreatorApplication | CreatorApplication | Empty string |
| Creation date | CreationDate | CreationDate | CreationDate | January 1, 0001 |
| Modification date | LastModificationDate | LastModificationDate | — | January 1, 0001 |
| Custom properties | UserDefinedDocumentProperties | UserDefinedDocumentProperties | UserDefinedDocumentProperties | null |
A PDF stores the title, author, subject, keywords, creating application and both dates. The standard properties are also saved with DOCX and the other formats, and the three objects work the same way for them.
Update the Metadata of an Existing PDF
To change a few values of a PDF, load it, change what you need and save it again. The following program adds keywords to a loaded PDF and records your application as the creator, while the title, author and subject of the original document stay:
using TXTextControl;
using (ServerTextControl tx = new ServerTextControl())
{
tx.Create();
tx.Load("Documents/input.pdf", StreamType.AdobePDF);
// Filled from the loaded PDF
DocumentSettings documentSettings = tx.DocumentSettings;
Console.WriteLine($"Title: {documentSettings.DocumentTitle}");
Console.WriteLine($"Created with: {documentSettings.CreatorApplication}");
// Stays with the document for every later save
documentSettings.DocumentKeywords = new string[] { "invoice", "INV-2025-001", "Acme Corporation" };
// Overrides the document settings for this file only
SaveSettings saveSettings = new SaveSettings()
{
CreatorApplication = "Invoice Service",
LastModificationDate = DateTime.Now
};
tx.Save("output.pdf", StreamType.AdobePDF, saveSettings);
}
The code works as follows:
- After
Load, DocumentSettings contains the metadata of the PDF. Values you change there are written by every laterSaveof this instance. SaveSettingssets onlyCreatorApplicationandLastModificationDate. All other metadata of the saved PDF comes fromDocumentSettings, so the original title, author and subject are kept.- Without the new
CreatorApplication, the saved PDF would still name the application that created the original file.
The saved PDF is a new document built from the loaded content, as Load and Modify a PDF explains.
Build a Keyword Index of Many PDFs
Search tools often rank metadata higher than body text, so keywords help users find PDF documents in large repositories. The following program reads the metadata of all PDF files in a folder and writes a JSON index:
using System.Text.Json;
using TXTextControl;
List<object> index = new List<object>();
using (ServerTextControl tx = new ServerTextControl())
{
tx.Create();
foreach (string file in Directory.GetFiles("Documents", "*.pdf"))
{
// Text only: the metadata doesn't need the layout of the pages
LoadSettings loadSettings = new LoadSettings()
{
PDFImportSettings = PDFImportSettings.GenerateLines
};
tx.Load(file, StreamType.AdobePDF, loadSettings);
index.Add(new
{
File = Path.GetFileName(file),
Title = loadSettings.DocumentTitle,
Author = loadSettings.Author,
Subject = loadSettings.DocumentSubject,
Keywords = (loadSettings.DocumentKeywords ?? Array.Empty<string>()).Select(keyword => keyword.Trim()).ToArray(),
Created = loadSettings.CreationDate == DateTime.MinValue ? (DateTime?)null : loadSettings.CreationDate
});
}
}
string json = JsonSerializer.Serialize(index, new JsonSerializerOptions { WriteIndented = true });
File.WriteAllText("index.json", json);
Console.WriteLine(json);
The code works as follows:
- One
ServerTextControlinstance loads the files one after the other; eachLoadreplaces the previous document. DocumentKeywordsisnullwhen a PDF has no keywords, which the index stores as an empty array.Trimremoves the spaces around each keyword.- A missing date is
DateTime.MinValue, which the index stores asnull.
The blog article Enhancing PDF Searchability in Large Repositories by Adding and Reading Keywords Using C# .NET recommends consistent tagging and 5 to 10 keywords per document.
Store Custom Properties
Besides the standard metadata, a document can carry properties of your own, such as an invoice number or the name of the data source a template uses. A UserDefinedPropertyDictionary holds them: each name is a string of up to 255 characters, and each value a string, a Boolean value, an integer or a double value. User-defined properties are saved and loaded with DOCX, RTF and the TX Text Control format, and with DOC on the Classic engine.
The following program updates the invoice number of a DOCX template and keeps all other properties it already has:
using TXTextControl;
using (ServerTextControl tx = new ServerTextControl())
{
tx.Create();
tx.Load("Documents/template.docx", StreamType.WordprocessingML);
UserDefinedPropertyDictionary properties =
tx.DocumentSettings.UserDefinedDocumentProperties ?? new UserDefinedPropertyDictionary();
// Replace the value of an existing property
if (properties.Contains("InvoiceNumber"))
{
properties.Remove("InvoiceNumber");
}
properties.Add("InvoiceNumber", "INV-2025-001");
tx.DocumentSettings.UserDefinedDocumentProperties = properties;
foreach (string name in properties.Names)
{
Console.WriteLine($"{name}: {properties[name]}");
}
tx.Save("Documents/template.docx", StreamType.WordprocessingML);
}
Contains checks for a name, Remove and Add change the entries, and the indexer Item returns the value of a name. Because the loaded properties are in DocumentSettings, Save keeps them without further code. MS Word users see the properties in the document's properties.
Give an Accessible PDF Its Title
PDF/UA, the standard for accessible PDF documents, requires a document title in DocumentSettings.DocumentTitle, as What Your Document Must Provide describes, and Check a Document Before Saving finds documents without one. A PDF created with TX Text Control contains its metadata in XMP format as well, together with the declaration that the document conforms to PDF/UA, and to PDF/A when it's saved with StreamType.AdobePDFA. To add XMP metadata of your own, such as the extension schema of an electronic invoice, pass it to the constructor of an embedded file, as Attachments shows.
Read the Raw Metadata of a PDF
With PDFImportSettings LoadEmbeddedData, Load also provides additional data of a PDF in LoadSettings.EmbeddedData, a dictionary whose keys are values of EmbeddedDataFormat and whose values are strings. The key MetaData returns the metadata of the PDF document:
using TXTextControl;
using (ServerTextControl tx = new ServerTextControl())
{
tx.Create();
LoadSettings loadSettings = new LoadSettings()
{
PDFImportSettings = PDFImportSettings.GenerateLines | PDFImportSettings.LoadEmbeddedData
};
tx.Load("Documents/input.pdf", StreamType.AdobePDF, loadSettings);
if (loadSettings.EmbeddedData != null &&
loadSettings.EmbeddedData.TryGetValue(EmbeddedDataFormat.MetaData, out object? metaData))
{
Console.WriteLine(metaData);
}
}
The dictionary is filled only when LoadEmbeddedData is set, and it contains only the formats the PDF provides. The other keys, TextCoordinates and FormFields, are used in Text Extraction and for PDF forms.
Next Steps
- PDF/UA: meet the other requirements of accessible PDF documents.
- Attachments: embed files with their own metadata.
- PDF Validation: check the title and metadata of the PDF documents you create.
- Document Properties in the Document Editor: set the properties in the browser.