Skip to content

Метаданные и XMP

PDF Oxide читает метаданные уровня документа из нескольких источников: заголовка PDF (версия), словарей trailer и catalog, потоков метаданных XMP (ISO 16684) и определений меток страниц. XmpExtractor разбирает пространства имён Dublin Core, XMP Core, PDF и XMP Rights, а также любые пользовательские свойства.

Используйте version() и catalog() для базовых свойств документа, XmpExtractor::extract() — для расширенных метаданных и PageLabelExtractor — для схем нумерации страниц.

Быстрый пример

Python

from pdf_oxide import PdfDocument

doc = PdfDocument("report.pdf")
major, minor = doc.version()
print(f"PDF {major}.{minor}, {doc.page_count()} pages")

Node.js

const { PdfDocument } = require("pdf-oxide");

const doc = new PdfDocument("report.pdf");
const { major, minor } = doc.getVersion();
console.log(`PDF ${major}.${minor}, ${doc.pageCount()} pages`);
doc.close();

Go

import pdfoxide "github.com/yfedoseev/pdf_oxide/go"

doc, _ := pdfoxide.Open("report.pdf")
defer doc.Close()
major, minor, _ := doc.Version()
pages, _ := doc.PageCount()
fmt.Printf("PDF %d.%d, %d pages\n", major, minor, pages)

C#

using PdfOxide.Core;

using var doc = PdfDocument.Open("report.pdf");
var (major, minor) = doc.Version;
Console.WriteLine($"PDF {major}.{minor}, {doc.PageCount} pages");

WASM

const doc = new WasmPdfDocument(bytes);
const version = doc.version();
console.log(`PDF ${version}, ${doc.pageCount()} pages`);

Rust

use pdf_oxide::PdfDocument;

let mut doc = PdfDocument::open("report.pdf")?;
let (major, minor) = doc.version();
println!("PDF {}.{}", major, minor);
println!("Pages: {}", doc.page_count()?);

Справочник API

version() -> (u8, u8)

Возвращает версию PDF из заголовка файла.

Возвращает: кортеж (major, minor), например (1, 7) для PDF 1.7 или (2, 0) для PDF 2.0.


catalog() -> Result<Object>

Возвращает словарь catalog документа. Catalog — это корень иерархии объектов PDF; он содержит ссылки на дерево страниц, закладки, имена и другие структуры уровня документа.

Rust

let mut doc = PdfDocument::open("report.pdf")?;
let catalog = doc.catalog()?;
if let Some(dict) = catalog.as_dict() {
    for (key, _) in dict {
        println!("Catalog key: {}", key);
    }
}

trailer() -> &Object

Возвращает словарь trailer документа. Trailer содержит расположение таблицы перекрёстных ссылок, идентификатор документа, ссылку на словарь шифрования и ссылку на словарь info.

Rust

let doc = PdfDocument::open("report.pdf")?;
let trailer = doc.trailer();
println!("Trailer: {:?}", trailer);

XmpExtractor::extract(doc) -> Result<Option<XmpMetadata>>

Извлекает метаданные XMP (Extensible Metadata Platform) из потока метаданных документа. XMP предоставляет более богатые метаданные, чем традиционный словарь Info, используя стандартные пространства имён XML.

Параметр Тип Описание
doc &mut PdfDocument Документ PDF

Возвращает: Some(XmpMetadata), если данные XMP присутствуют, иначе None.

Поля XmpMetadata

Пространство имён Dublin Core (dc:)

Поле Тип Описание
dc_title Option<String> Заголовок документа
dc_creator Vec<String> Список авторов/создателей
dc_description Option<String> Описание документа
dc_subject Vec<String> Ключевые слова темы
dc_language Option<String> Язык документа (например, "en-US")
dc_rights Option<String> Сведения об авторских правах
dc_format Option<String> MIME-формат (например, "application/pdf")

Пространство имён XMP Core (xmp:)

Поле Тип Описание
xmp_creator_tool Option<String> Инструмент, которым создан документ
xmp_create_date Option<String> Дата создания (ISO 8601)
xmp_modify_date Option<String> Дата последнего изменения
xmp_metadata_date Option<String> Дата изменения метаданных

Пространство имён PDF (pdf:)

Поле Тип Описание
pdf_producer Option<String> Приложение-производитель PDF
pdf_keywords Option<String> Строка ключевых слов
pdf_version Option<String> Версия PDF из XMP (может отличаться от заголовка)
pdf_trapped Option<String> Статус треппинга

Пространство имён XMP Rights (xmpRights:)

Поле Тип Описание
xmp_rights_usage_terms Option<String> Условия использования
xmp_rights_marked Option<bool> Помечен ли документ сведениями о правах
xmp_rights_web_statement Option<String> URL веб-заявления о правах

Прочее

Поле Тип Описание
custom HashMap<String, String> Пользовательские свойства (namespace:property → значение)
raw_xml Option<String> Исходный XML-пакет XMP

Rust

use pdf_oxide::extractors::xmp::XmpExtractor;

let mut doc = PdfDocument::open("report.pdf")?;
if let Some(xmp) = XmpExtractor::extract(&mut doc)? {
    if let Some(title) = &xmp.dc_title {
        println!("Title: {}", title);
    }
    for creator in &xmp.dc_creator {
        println!("Author: {}", creator);
    }
    if let Some(tool) = &xmp.xmp_creator_tool {
        println!("Created with: {}", tool);
    }
    if let Some(date) = &xmp.xmp_create_date {
        println!("Created: {}", date);
    }
    if let Some(producer) = &xmp.pdf_producer {
        println!("Producer: {}", producer);
    }
}

WASM

const doc = new WasmPdfDocument(bytes);
const xmp = doc.xmpMetadata();

if (xmp) {
  console.log(`Title: ${xmp.dc_title}`);
  console.log(`Authors: ${xmp.dc_creator}`);
  console.log(`Created with: ${xmp.xmp_creator_tool}`);
  console.log(`Created: ${xmp.xmp_create_date}`);
  console.log(`Producer: ${xmp.pdf_producer}`);
}
doc.free();

Python

doc = PdfDocument("report.pdf")
xmp = doc.xmp_metadata()

if xmp:
    print(f"Title: {xmp.get('dc_title')}")
    print(f"Authors: {xmp.get('dc_creator')}")
    print(f"Created with: {xmp.get('xmp_creator_tool')}")
    print(f"Created: {xmp.get('xmp_create_date')}")
    print(f"Producer: {xmp.get('pdf_producer')}")

<!-- Node.js: no equivalent on PdfDocumentImpl — xmp metadata not exposed in js/src/index.ts -->

Go

doc, _ := pdfoxide.Open("report.pdf")
defer doc.Close()
xmp, _ := doc.XmpMetadata() // returns JSON string
fmt.Println(xmp)

C#

using var doc = PdfDocument.Open("report.pdf");
var xmp = doc.GetXmpMetadata(); // returns JSON string
Console.WriteLine(xmp);

Удобные методы Pdf

Высокоуровневый API Pdf предоставляет сокращённые методы для типичных запросов метаданных.

xmp_metadata() -> Result<Option<XmpMetadata>>

Возвращает полный объект метаданных XMP.

xmp_title() -> Result<Option<String>>

Возвращает только заголовок документа из XMP.

xmp_creators() -> Result<Vec<String>>

Возвращает список создателей/авторов из XMP.

Rust

use pdf_oxide::api::Pdf;

let mut pdf = Pdf::open("report.pdf")?;

if let Some(title) = pdf.xmp_title()? {
    println!("Title: {}", title);
}

let creators = pdf.xmp_creators()?;
for creator in &creators {
    println!("Author: {}", creator);
}

PageLabelExtractor::extract(doc) -> Result<Vec<PageLabelRange>>

Извлекает определения меток страниц из документа. Метки страниц определяют, как отображаются номера страниц (например, римские цифры для вступительной части, арабские — для основного текста).

Параметр Тип Описание
doc &mut PdfDocument Документ PDF

Возвращает: вектор определений PageLabelRange.

Поля PageLabelRange

Поле Тип Описание
start_page usize Индекс первой страницы, к которой применяется диапазон
style PageLabelStyle Стиль нумерации
prefix Option<String> Строка-префикс метки
start_number u32 Начальный номер для этого диапазона

Варианты PageLabelStyle

Вариант Описание Пример
DecimalArabic Арабские цифры 1, 2, 3
UppercaseRoman Прописные римские I, II, III
LowercaseRoman Строчные римские i, ii, iii
UppercaseLetters Прописные буквы A, B, C
LowercaseLetters Строчные буквы a, b, c
None Без нумерации (только префикс)

Удобные методы Pdf для меток страниц

page_labels() -> Result<Vec<PageLabelRange>>

Возвращает все определения диапазонов меток страниц.

page_label(page) -> Result<String>

Возвращает отображаемую метку для конкретного индекса страницы.

Rust

use pdf_oxide::api::Pdf;

let mut pdf = Pdf::open("book.pdf")?;

// Get all label ranges
let ranges = pdf.page_labels()?;
for range in &ranges {
    println!(
        "Pages from {}: {:?} style, prefix={:?}, start={}",
        range.start_page, range.style, range.prefix, range.start_number
    );
}

// Get label for a specific page
let label = pdf.page_label(0)?;
println!("Page 0 label: {}", label); // e.g., "i" or "Cover"

WASM

const doc = new WasmPdfDocument(bytes);
const labels = doc.pageLabels();

for (const range of labels) {
  console.log(`Pages from ${range.start_page}: style=${range.style}, prefix=${range.prefix}`);
}
doc.free();

Python

doc = PdfDocument("book.pdf")
labels = doc.page_labels()

for range in labels:
    print(f"Pages from {range['start_page']}: style={range['style']}, prefix={range['prefix']}")

<!-- Node.js: no equivalent on PdfDocumentImpl — pageLabels not exposed on class, only via properties mixin -->

Go

doc, _ := pdfoxide.Open("book.pdf")
defer doc.Close()
labels, _ := doc.PageLabels() // returns JSON string
fmt.Println(labels)

C#

using var doc = PdfDocument.Open("book.pdf");
var labels = doc.GetPageLabels(); // returns JSON string
Console.WriteLine(labels);

Расширенные примеры

Вывод полных метаданных документа

use pdf_oxide::PdfDocument;
use pdf_oxide::extractors::xmp::XmpExtractor;

let mut doc = PdfDocument::open("report.pdf")?;

// Basic info
let (major, minor) = doc.version();
println!("PDF Version: {}.{}", major, minor);
println!("Pages: {}", doc.page_count()?);

// XMP metadata
if let Some(xmp) = XmpExtractor::extract(&mut doc)? {
    println!("\nXMP Metadata:");
    println!("  Title:       {:?}", xmp.dc_title);
    println!("  Authors:     {:?}", xmp.dc_creator);
    println!("  Description: {:?}", xmp.dc_description);
    println!("  Keywords:    {:?}", xmp.pdf_keywords);
    println!("  Creator:     {:?}", xmp.xmp_creator_tool);
    println!("  Producer:    {:?}", xmp.pdf_producer);
    println!("  Created:     {:?}", xmp.xmp_create_date);
    println!("  Modified:    {:?}", xmp.xmp_modify_date);
    println!("  Language:    {:?}", xmp.dc_language);
    println!("  Rights:      {:?}", xmp.dc_rights);

    if !xmp.custom.is_empty() {
        println!("\n  Custom properties:");
        for (key, value) in &xmp.custom {
            println!("    {}: {}", key, value);
        }
    }
}

Доступ к необработанному XML XMP

use pdf_oxide::extractors::xmp::XmpExtractor;

let mut doc = PdfDocument::open("report.pdf")?;
if let Some(xmp) = XmpExtractor::extract(&mut doc)? {
    if let Some(xml) = &xmp.raw_xml {
        std::fs::write("metadata.xml", xml)?;
        println!("Raw XMP saved ({} bytes)", xml.len());
    }
}

Формирование строк отображения номеров страниц

use pdf_oxide::api::Pdf;

let mut pdf = Pdf::open("thesis.pdf")?;
let page_count = pdf.page_count()?;

for i in 0..page_count {
    let label = pdf.page_label(i)?;
    println!("Physical page {} -> display label '{}'", i + 1, label);
}
// Example output:
//   Physical page 1 -> display label 'i'
//   Physical page 2 -> display label 'ii'
//   Physical page 3 -> display label 'iii'
//   Physical page 4 -> display label '1'
//   Physical page 5 -> display label '2'

Связанные страницы