Метаданные и 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'
Связанные страницы
- Извлечение текста – Извлечение текстового содержимого со страниц
- Извлечение аннотаций – Доступ к закладкам и аннотациям
- Извлечение данных форм – Извлечение данных полей формы