PDF/UA-Validierung
PDF/UA (ISO 14289) definiert Anforderungen für universell zugängliche PDF-Dokumente. PDF Oxide validiert Strukturbäume, Überschriftensequenzen, Alternativtext, Tabellenüberschriften, Sprachdeklarationen und mehr.
Unterstützte Stufen
| Stufe | Standard | Beschreibung |
|---|---|---|
| PDF/UA-1 | ISO 14289-1:2014 | Grundlegende Barrierefreiheitsanforderungen |
| PDF/UA-2 | ISO 14289-2:2024 | Erweiterte Anforderungen, ausgerichtet an WCAG 2.1 |
Schnellvalidierung
from pdf_oxide import PdfDocument
doc = PdfDocument("document.pdf")
result = doc.validate_pdf_ua()
print(f"Valid: {result.valid}")
for error in result.errors:
print(f" {error}")
use pdf_oxide::PdfDocument;
use pdf_oxide::compliance::{validate_pdf_ua, PdfUaLevel};
let mut doc = PdfDocument::open("accessible.pdf")?;
let result = validate_pdf_ua(&mut doc, PdfUaLevel::UA1)?;
if result.has_errors() {
println!("Not PDF/UA-1 compliant:");
for error in &result.errors {
println!(" [{}] {} (clause {})",
error.code, error.message,
error.clause.as_deref().unwrap_or("n/a"));
}
} else {
println!("Document is PDF/UA-1 compliant");
}
Validator-API
Der PdfUaValidator-Builder ermöglicht die Konfiguration spezifischer Prüfungen:
use pdf_oxide::PdfDocument;
use pdf_oxide::compliance::{PdfUaValidator, PdfUaLevel};
let mut doc = PdfDocument::open("report.pdf")?;
let result = PdfUaValidator::new()
.check_heading_sequence(true)
.check_color_contrast(true)
.allow_custom_types(vec!["Caption".into(), "Aside".into()])
.validate(&mut doc, PdfUaLevel::UA1)?;
println!("Errors: {}", result.errors.len());
println!("Warnings: {}", result.warnings.len());
println!("Structure elements checked: {}",
result.stats.structure_elements_checked);
Konfigurationsoptionen
| Methode | Standard | Beschreibung |
|---|---|---|
check_heading_sequence(bool) |
true |
Validieren, dass H1-H6 keine Ebenen überspringen |
check_color_contrast(bool) |
true |
Potenzielle Kontrastprobleme markieren |
allow_custom_types(Vec<String>) |
[] |
Nicht-standardmäßige Strukturtypen ohne Warnung erlauben |
Strukturbaum-Inspektion
Vor der Validierung können Sie den Strukturbaum und die Mark-Info des Dokuments inspizieren:
use pdf_oxide::PdfDocument;
let mut doc = PdfDocument::open("tagged.pdf")?;
// Check if the document claims to be tagged
let mark_info = doc.mark_info()?;
println!("Marked: {}", mark_info.marked);
println!("Suspects: {}", mark_info.suspects);
// Access the structure tree
if let Some(tree) = doc.structure_tree()? {
println!("Root tag: {}", tree.root_type);
println!("Children: {}", tree.children.len());
}
Die Methode mark_info() gibt zurück:
| Feld | Typ | Beschreibung |
|---|---|---|
marked |
bool |
Ob das Dokument sich als getaggt deklariert |
suspects |
bool |
Ob Tag-Zuweisungen möglicherweise inkorrekt sind |
user_properties |
bool |
Ob Benutzereigenschaften vorhanden sind |
Wenn suspects true ist, fällt PDF Oxide automatisch auf geometrische Ordnung für die Textextraktion zurück, anstatt sich auf den potenziell unzuverlässigen Strukturbaum zu verlassen.
Was geprüft wird
Der Validator deckt die folgenden PDF/UA-Anforderungen ab:
Dokumentebene
| Prüfung | Klausel | Beschreibung |
|---|---|---|
| Sprache | 7.2 | /Lang-Eintrag im Katalog vorhanden |
| Titel | 7.1 | Dokumenttitel gesetzt und in der Titelleiste angezeigt |
| Getaggt | 7.1 | MarkInfo-Wörterbuch deklariert Marked = true |
| XMP-Metadaten | 7.1 | pdfuaid:part im XMP-Stream deklariert |
Struktur
| Prüfung | Klausel | Beschreibung |
|---|---|---|
| Strukturbaum | 7.1 | Vollständiger Strukturbaum mit Wurzel bei StructTreeRoot |
| Rollenzuordnung | 7.5 | Nicht-standardmäßige Typen auf Standard-Strukturelemente abgebildet |
| Überschriftenhierarchie | 7.4.2 | Überschriften (H1-H6) überspringen keine Ebenen |
| Artefakt-Markierung | 7.3 | Dekorativer Inhalt als Artefakt markiert |
| Lesereihenfolge | 7.2 | Strukturbaum definiert eine logische Lesereihenfolge |
Inhalt
| Prüfung | Klausel | Beschreibung |
|---|---|---|
| Alternativtext für Bilder | 7.3 | /Alt oder /ActualText auf Figure-Elementen |
| Tabellenüberschriften | 7.5 | TH-Elemente in Tabellenstrukturen vorhanden |
| Formularbeschriftungen | 7.6.2 | Formularfelder haben zugehörige Beschriftungen oder Tooltips |
| Linktext | 7.18 | Link-Anmerkungen haben beschreibenden Inhalt |
| Listenstruktur | 7.4.3 | Listen verwenden L, LI, Lbl, LBody-Struktur |
Schrift und Text
| Prüfung | Klausel | Beschreibung |
|---|---|---|
| Unicode-Zuordnung | 7.21.3 | Aller Text hat eine Unicode-Darstellung |
| Schrifteinbettung | 7.21.4 | Schriften eingebettet oder Standard-Base14-Schriften |
| ActualText | 7.21.5 | Ligaturen und Spezialglyphen haben /ActualText |
UaValidationResult
pub struct UaValidationResult {
pub level: PdfUaLevel,
pub errors: Vec<UaComplianceError>,
pub warnings: Vec<ComplianceWarning>,
pub stats: UaValidationStats,
}
UaComplianceError
Jeder Fehler enthält optionale WCAG-Ausrichtung:
pub struct UaComplianceError {
pub code: UaErrorCode,
pub message: String,
pub location: Option<String>,
pub wcag_ref: Option<String>,
pub clause: Option<String>,
}
Das wcag_ref-Feld ordnet den PDF/UA-Verstoß dem entsprechenden WCAG-Erfolgskriterium zu (e.g., "1.1.1" for non-text content, "1.3.1" for info and relationships).
UaErrorCode Categories
Das UaErrorCode-Enum enthält Fehlerkategorien wie:
MissingLanguage– no/Langentry on the document catalogMissingStructureTree– document is not taggedMissingAltText– Figure element lacks alt textHeadingSkipped– heading levels jump (e.g., H1 to H3)MissingTableHeaders– table lacksTHelementsFormFieldNoLabel– form field has no associated labelInvalidRoleMapping– non-standard type not mapped to a standard elementArtifactNotMarked– decorative content not marked as artifactMissingUnicode– text without Unicode mapping
Praktisches Beispiel: Barrierefreiheitsbericht
Einen menschenlesbaren Barrierefreiheitsbericht aus Validierungsergebnissen erstellen:
use pdf_oxide::PdfDocument;
use pdf_oxide::compliance::{validate_pdf_ua, PdfUaLevel};
let mut doc = PdfDocument::open("document.pdf")?;
let result = validate_pdf_ua(&mut doc, PdfUaLevel::UA1)?;
println!("=== PDF/UA Accessibility Report ===");
println!("Level: PDF/UA-{}", result.level.xmp_part());
println!("Status: {}", if result.has_errors() { "FAIL" } else { "PASS" });
println!();
if result.has_errors() {
println!("Errors ({}):", result.errors.len());
for (i, error) in result.errors.iter().enumerate() {
print!(" {}. [{}] {}", i + 1, error.code, error.message);
if let Some(ref wcag) = error.wcag_ref {
print!(" (WCAG {})", wcag);
}
println!();
}
}
if result.has_warnings() {
println!("\nWarnings ({}):", result.warnings.len());
for warning in &result.warnings {
println!(" - [{}] {}", warning.code, warning.message);
}
}
println!("\nStats:");
println!(" Structure elements checked: {}",
result.stats.structure_elements_checked);
Nächste Schritte
- PDF/A-Validierung – Archivierungskonformität
- PDF/X-Druckproduktion – Druckproduktionskonformität
- API-Referenz – vollständige Rust-API