ZingPDF logo

Guide

How to inspect the PDF object graph in C#

Use pdf.Objects for syntax-level inspection of the catalog, trailer, page tree, and indirect objects.

Prefer high-level wrappers for ordinary document edits. Low-level access is for integrations that require PDF object details that are not yet wrapped by a feature-specific API.

Read the catalog and trailer

The catalog and latest trailer are the usual starting points for document-level structure.

using ZingPDF;

using var pdf = Pdf.Load(File.OpenRead("input.pdf"));

var catalog = await pdf.Objects.GetDocumentCatalogAsync();
var trailer = await pdf.Objects.GetLatestTrailerDictionaryAsync();

Console.WriteLine($"Root reference: {trailer.Root}");
Console.WriteLine($"Catalog object type: {catalog.GetType().Name}");

Inspect the page tree

pdf.Objects.PageTree exposes page-tree helpers below the public Pdf.GetPageAsync(...) API.

var pageCount = await pdf.Objects.PageTree.GetPageCountAsync();
Console.WriteLine($"Pages: {pageCount}");

await foreach (var pageObject in pdf.Objects.PageTree.EnumeratePagesAsync())
{
    Console.WriteLine($"Page object: {pageObject.Id}");
}

Enumerate indirect objects

The object collection is asynchronous because object streams and referenced objects can be parsed on demand.

await foreach (var indirectObject in pdf.Objects)
{
    Console.WriteLine($"{indirectObject.Id}: {indirectObject.Object.GetType().Name}");
}

Editing cautions

  • Prefer typed wrappers such as Form, Page, metadata, redaction, and signing APIs when they cover the task.
  • Direct object mutations can produce invalid PDFs if required dictionary entries, references, xref state, or stream lengths are wrong.
  • After replacing an indirect object, call pdf.Objects.Update(indirectObject) so the save pipeline writes the changed object.
  • Delete(...) marks the object as free in the next update. It does not scrub previous bytes from older file revisions.

Next step

For high-level save behavior and history removal, see How to rewrite a PDF without incremental history in C#.