Metadatos y XMP
PDF Oxide lee los metadatos a nivel de documento desde múltiples fuentes: la cabecera del PDF (versión), los diccionarios trailer y catalog, los flujos de metadatos XMP (ISO 16684) y las definiciones de etiquetas de página. El XmpExtractor analiza los namespaces de Dublin Core, XMP Core, PDF y XMP Rights, además de cualquier propiedad personalizada.
Usa version() y catalog() para las propiedades básicas del documento, XmpExtractor::extract() para los metadatos enriquecidos y PageLabelExtractor para los esquemas de numeración de páginas.
Ejemplo rápido
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()?);
Referencia de API
version() -> (u8, u8)
Obtiene la versión del PDF a partir de la cabecera del archivo.
Devuelve: Una tupla de (major, minor), p. ej., (1, 7) para PDF 1.7 o (2, 0) para PDF 2.0.
catalog() -> Result<Object>
Obtiene el diccionario catalog del documento. El catalog es la raíz de la jerarquía de objetos del PDF y contiene referencias al árbol de páginas, los marcadores (outlines), los nombres y otras estructuras a nivel de documento.
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
Obtiene el diccionario trailer del documento. El trailer contiene la ubicación de la tabla de referencias cruzadas, el ID del documento, la referencia al diccionario de cifrado y la referencia al diccionario info.
Rust
let doc = PdfDocument::open("report.pdf")?;
let trailer = doc.trailer();
println!("Trailer: {:?}", trailer);
XmpExtractor::extract(doc) -> Result<Option<XmpMetadata>>
Extrae los metadatos XMP (Extensible Metadata Platform) del flujo de metadatos del documento. XMP proporciona metadatos más ricos que el diccionario Info tradicional, usando namespaces XML estándar.
| Parámetro | Tipo | Descripción |
|---|---|---|
doc |
&mut PdfDocument |
El documento PDF |
Devuelve: Some(XmpMetadata) si hay datos XMP presentes, None en caso contrario.
Campos de XmpMetadata
Namespace Dublin Core (dc:)
| Campo | Tipo | Descripción |
|---|---|---|
dc_title |
Option<String> |
Título del documento |
dc_creator |
Vec<String> |
Lista de autores/creadores |
dc_description |
Option<String> |
Descripción del documento |
dc_subject |
Vec<String> |
Palabras clave del tema |
dc_language |
Option<String> |
Idioma del documento (p. ej., "en-US") |
dc_rights |
Option<String> |
Declaración de copyright |
dc_format |
Option<String> |
Formato MIME (p. ej., "application/pdf") |
Namespace XMP Core (xmp:)
| Campo | Tipo | Descripción |
|---|---|---|
xmp_creator_tool |
Option<String> |
Herramienta usada para crear el documento |
xmp_create_date |
Option<String> |
Fecha de creación (ISO 8601) |
xmp_modify_date |
Option<String> |
Fecha de última modificación |
xmp_metadata_date |
Option<String> |
Fecha de modificación de los metadatos |
Namespace PDF (pdf:)
| Campo | Tipo | Descripción |
|---|---|---|
pdf_producer |
Option<String> |
Aplicación productora del PDF |
pdf_keywords |
Option<String> |
Cadena de palabras clave |
pdf_version |
Option<String> |
Versión del PDF según XMP (puede diferir de la cabecera) |
pdf_trapped |
Option<String> |
Estado de trapping |
Namespace XMP Rights (xmpRights:)
| Campo | Tipo | Descripción |
|---|---|---|
xmp_rights_usage_terms |
Option<String> |
Términos de uso |
xmp_rights_marked |
Option<bool> |
Si está marcado con derechos |
xmp_rights_web_statement |
Option<String> |
URL de la declaración web |
Otros
| Campo | Tipo | Descripción |
|---|---|---|
custom |
HashMap<String, String> |
Propiedades personalizadas (namespace:propiedad a valor) |
raw_xml |
Option<String> |
El paquete XML XMP original |
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);
Métodos de conveniencia de Pdf
La API de alto nivel Pdf proporciona métodos abreviados para las consultas de metadatos más habituales.
xmp_metadata() -> Result<Option<XmpMetadata>>
Obtiene el objeto completo de metadatos XMP.
xmp_title() -> Result<Option<String>>
Obtiene solo el título del documento desde XMP.
xmp_creators() -> Result<Vec<String>>
Obtiene la lista de creadores/autores desde 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>>
Extrae las definiciones de etiquetas de página del documento. Las etiquetas de página definen cómo se muestran los números de página (p. ej., números romanos para las páginas preliminares, números arábigos para el cuerpo).
| Parámetro | Tipo | Descripción |
|---|---|---|
doc |
&mut PdfDocument |
El documento PDF |
Devuelve: Un vector de definiciones PageLabelRange.
Campos de PageLabelRange
| Campo | Tipo | Descripción |
|---|---|---|
start_page |
usize |
Primer índice de página al que se aplica este rango |
style |
PageLabelStyle |
Estilo de numeración |
prefix |
Option<String> |
Cadena de prefijo de la etiqueta |
start_number |
u32 |
Número inicial de este rango |
Variantes de PageLabelStyle
| Variante | Descripción | Ejemplo |
|---|---|---|
DecimalArabic |
Números arábigos | 1, 2, 3 |
UppercaseRoman |
Romanos en mayúscula | I, II, III |
LowercaseRoman |
Romanos en minúscula | i, ii, iii |
UppercaseLetters |
Letras mayúsculas | A, B, C |
LowercaseLetters |
Letras minúsculas | a, b, c |
None |
Sin numeración (solo prefijo) | – |
Métodos de conveniencia de etiquetas de página de Pdf
page_labels() -> Result<Vec<PageLabelRange>>
Obtiene todas las definiciones de rangos de etiquetas de página.
page_label(page) -> Result<String>
Obtiene la etiqueta visible para un índice de página específico.
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);
Ejemplos avanzados
Mostrar los metadatos completos del documento
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);
}
}
}
Acceder al XML XMP sin procesar
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());
}
}
Generar las cadenas visibles de numeración de páginas
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'
Páginas relacionadas
- Extracción de texto – Extrae el contenido de texto de las páginas
- Extracción de anotaciones – Accede a los marcadores y las anotaciones
- Extracción de datos de formulario – Extrae los datos de los campos de formulario