PDF/A-Validierung
PDF/A (ISO 19005) ist der internationale Standard für die langfristige Archivierung elektronischer Dokumente. PDF Oxide validiert alle wichtigen PDF/A-Stufen und kann nicht konforme Dokumente in Richtung Konformität konvertieren.
Abdeckung in den Bindings. Die PDF/A-Validierung ist in Python (
doc.validate_pdf_a(level)), Rust (validate_pdf_a+PdfAValidator-Builder), WASM (doc.validatePdfA(level)) und Go (doc.ValidatePdfA(level)) verfügbar. Ein öffentlicher C#-Wrapper ist noch nicht bereitgestellt – verwenden Sie die Rust-CLI (pdf-oxide validate --pdfa 2b doc.pdf) oder rufen Sie über eine der unterstützten Bindings auf. Die PDF/A-Konvertierung (PdfAConverter) ist derzeit nur in Rust und Python verfügbar.
Unterstützte Stufen
| Stufe | Standard | Struktur | Unicode | Transparenz | Eingebettete Dateien |
|---|---|---|---|---|---|
| 1a | ISO 19005-1 | Erforderlich | Erforderlich | Nein | Nein |
| 1b | ISO 19005-1 | Nein | Nein | Nein | Nein |
| 2a | ISO 19005-2 | Erforderlich | Erforderlich | Ja | Nein |
| 2b | ISO 19005-2 | Nein | Nein | Ja | Nein |
| 2u | ISO 19005-2 | Nein | Erforderlich | Ja | Nein |
| 3a | ISO 19005-3 | Erforderlich | Erforderlich | Ja | Ja |
| 3b | ISO 19005-3 | Nein | Nein | Ja | Ja |
| 3u | ISO 19005-3 | Nein | Erforderlich | Ja | Ja |
Stufe „a“ (accessible, barrierefrei) erfordert einen getaggten Strukturbaum und eine Zeichenzuordnung zu Unicode. Stufe „b“ (basic, einfach) erfordert lediglich die visuelle Reproduzierbarkeit. Stufe „u“ (Unicode) erfordert eine Textzuordnung zu Unicode ohne den vollständigen Strukturbaum.
Schnelle Validierung
Verwenden Sie die Komfortfunktion für eine Prüfung mit einem einzigen Aufruf:
from pdf_oxide import PdfDocument
doc = PdfDocument("document.pdf")
result = doc.validate_pdf_a("2b")
print(f"Valid: {result.valid}")
print(f"Level: {result.level}")
for error in result.errors:
print(f" Error: {error}")
const doc = new WasmPdfDocument(bytes);
const result = doc.validatePdfA("2b");
console.log(`Valid: ${result.valid}`);
console.log(`Errors: ${result.errors.length}`);
doc.free();
use pdf_oxide::PdfDocument;
use pdf_oxide::compliance::{validate_pdf_a, PdfALevel};
let mut doc = PdfDocument::open("archive.pdf")?;
let result = validate_pdf_a(&mut doc, PdfALevel::A1b)?;
if result.has_errors() {
println!("Not PDF/A-1b 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/A-1b compliant");
}
package main
import (
"fmt"
"log"
pdfoxide "github.com/yfedoseev/pdf_oxide/go"
)
func main() {
doc, err := pdfoxide.Open("archive.pdf")
if err != nil { log.Fatal(err) }
defer doc.Close()
// Level encoding: 0 = 1b, 1 = 1a, 2 = 2b, 3 = 2a, 4 = 2u, 5 = 3b, 6 = 3a, 7 = 3u
result, err := doc.ValidatePdfA(0) // PDF/A-1b
if err != nil { log.Fatal(err) }
if result.Valid {
fmt.Println("Document is PDF/A-1b compliant")
} else {
fmt.Println("Not PDF/A-1b compliant:")
for _, e := range result.Errors {
fmt.Printf(" %s\n", e)
}
}
}
Validator-API
Der PdfAValidator bietet ein Builder-Muster für eine feingranulare Steuerung:
use pdf_oxide::PdfDocument;
use pdf_oxide::compliance::{PdfAValidator, PdfALevel};
let mut doc = PdfDocument::open("report.pdf")?;
let result = PdfAValidator::new()
.stop_on_first_error(false)
.include_warnings(true)
.validate(&mut doc, PdfALevel::A2b)?;
println!("Errors: {}", result.errors.len());
println!("Warnings: {}", result.warnings.len());
Gezielte Prüfungen
Führen Sie einzelne Validierungskategorien anstelle der vollständigen Suite aus:
use pdf_oxide::PdfDocument;
use pdf_oxide::compliance::{PdfAValidator, PdfALevel};
let mut doc = PdfDocument::open("report.pdf")?;
let validator = PdfAValidator::new();
// Check only metadata
let result = validator.check_metadata(&mut doc, PdfALevel::A1b)?;
// Check only fonts
let result = validator.check_fonts(&mut doc, PdfALevel::A1b)?;
// Check only color spaces
let result = validator.check_colors(&mut doc, PdfALevel::A1b)?;
// Check only transparency
let result = validator.check_transparency(&mut doc, PdfALevel::A2b)?;
// Check only structure tags
let result = validator.check_structure(&mut doc, PdfALevel::A1a)?;
Eigenständige Validatoren
Jede Validierungskategorie ist für maximale Flexibilität auch als eigenständige Funktion verfügbar:
use pdf_oxide::PdfDocument;
use pdf_oxide::compliance::validators::*;
use pdf_oxide::compliance::{PdfALevel, ValidationResult};
let mut doc = PdfDocument::open("document.pdf")?;
let mut result = ValidationResult::new(PdfALevel::A1b);
// Run each validator independently
validate_xmp_metadata(&mut doc, PdfALevel::A1b, &mut result)?;
validate_fonts(&mut doc, PdfALevel::A1b, &mut result)?;
validate_colors(&mut doc, PdfALevel::A1b, &mut result)?;
validate_encryption(&mut doc, PdfALevel::A1b, &mut result)?;
validate_transparency(&mut doc, PdfALevel::A1b, &mut result)?;
validate_structure(&mut doc, PdfALevel::A1b, &mut result)?;
validate_javascript(&mut doc, PdfALevel::A1b, &mut result)?;
validate_embedded_files(&mut doc, PdfALevel::A1b, &mut result)?;
validate_annotations(&mut doc, PdfALevel::A1b, &mut result)?;
println!("Total errors: {}", result.errors.len());
Validator-Übersicht
| Funktion | Was sie prüft |
|---|---|
validate_xmp_metadata() |
XMP-Stream vorhanden, Einträge pdfaid:part und pdfaid:conformance vorhanden, Konsistenz der Metadaten |
validate_fonts() |
Alle Schriften eingebettet, Glyphenbreiten vorhanden, Unicode-Zuordnung verfügbar (für Stufe „a“ und „u“) |
validate_colors() |
Keine geräteabhängigen Farboperatoren (rg, RG, k, K, g, G) ohne Output Intent |
validate_encryption() |
In PDF/A-Dokumenten ist keine Verschlüsselung zulässig |
validate_transparency() |
Keine Transparenz in PDF/A-1; in PDF/A-2 und später erlaubt |
validate_structure() |
Getaggter Strukturbaum mit gültiger Rollenzuordnung vorhanden (für Stufe „a“ erforderlich) |
validate_javascript() |
Keine JavaScript-Aktionen oder -Trigger vorhanden |
validate_embedded_files() |
In PDF/A-1 oder PDF/A-2 nicht zulässig; PDF/A-3 erfordert den Schlüssel AFRelationship bei jeder Dateispezifikation |
validate_annotations() |
Annotationstypen gemäß dem jeweiligen Teil der ISO 19005 eingeschränkt |
ValidationResult
Die Struktur ValidationResult enthält das vollständige Ergebnis eines Validierungslaufs:
pub struct ValidationResult {
pub level: PdfALevel,
pub errors: Vec<ComplianceError>,
pub warnings: Vec<ComplianceWarning>,
pub stats: ValidationStats,
}
| Feld | Typ | Beschreibung |
|---|---|---|
level |
PdfALevel |
Die angestrebte Konformitätsstufe |
errors |
Vec<ComplianceError> |
Blockierende Verstöße, die die Konformität verhindern |
warnings |
Vec<ComplianceWarning> |
Nicht blockierende Probleme, die die Qualität beeinträchtigen können |
stats |
ValidationStats |
Anzahl der geprüften Seiten, Schriften und Objekte |
ComplianceError
pub struct ComplianceError {
pub code: ErrorCode,
pub message: String,
pub location: Option<String>,
pub clause: Option<String>,
}
Das Feld code verwendet die Enumeration ErrorCode mit Kategorien wie MissingXmpMetadata, FontNotEmbedded, DeviceDependentColor, EncryptionPresent, TransparencyNotAllowed, MissingStructureTree, JavaScriptPresent und InvalidEmbeddedFile.
ComplianceWarning
pub struct ComplianceWarning {
pub code: WarningCode,
pub message: String,
pub location: Option<String>,
}
PDF/A-Konvertierung
Konvertieren Sie ein nicht konformes Dokument in Richtung PDF/A-Konformität:
use pdf_oxide::PdfDocument;
use pdf_oxide::compliance::{convert_to_pdf_a, PdfALevel};
let mut doc = PdfDocument::open("input.pdf")?;
let result = convert_to_pdf_a(&mut doc, PdfALevel::A1b)?;
println!("Conversion actions taken:");
for action in &result.actions {
println!(" - {}: {}", action.action_type, action.description);
}
if result.remaining_errors.is_empty() {
println!("Document is now PDF/A-1b compliant");
} else {
println!("{} issues could not be resolved automatically",
result.remaining_errors.len());
}
Konvertierungskonfiguration
Stimmen Sie den Konvertierungsprozess fein ab:
use pdf_oxide::PdfDocument;
use pdf_oxide::compliance::{PdfAConverter, PdfALevel, ConversionConfig};
let mut doc = PdfDocument::open("input.pdf")?;
let config = ConversionConfig::new()
.embed_fonts(true)
.remove_javascript(true)
.flatten_transparency(true)
.add_structure(true);
let result = PdfAConverter::new(PdfALevel::A2b)
.with_config(config)
.convert(&mut doc)?;
Der Konverter führt diese Aktionen automatisch aus:
- Einfügen von XMP-Metadaten – fügt die Einträge
pdfaid:partundpdfaid:conformancehinzu - Schrifteinbettung – bettet alle referenzierten, aber nicht eingebetteten Schriften ein
- Entfernen von JavaScript – entfernt JavaScript-Aktionen und -Trigger
- Reduzieren der Transparenz – rendert transparente Elemente als undurchsichtig (nur PDF/A-1)
- ICC-Profil-Konvertierung – wandelt geräteabhängige Farben in ICC-basierte Farbräume um
- Struktur-Tagging – fügt grundlegende Struktur-Tags hinzu (für Ziele der Stufe „a“)
Workflow: Validieren, Korrigieren, Erneut validieren
Ein typischer Archivierungs-Workflow validiert, versucht eine automatische Konvertierung und validiert anschließend erneut:
use pdf_oxide::PdfDocument;
use pdf_oxide::compliance::{validate_pdf_a, convert_to_pdf_a, PdfALevel};
let level = PdfALevel::A2b;
let mut doc = PdfDocument::open("input.pdf")?;
// Step 1: Initial validation
let result = validate_pdf_a(&mut doc, level)?;
if !result.has_errors() {
println!("Already compliant");
return Ok(());
}
println!("{} errors found, attempting conversion...", result.errors.len());
// Step 2: Automatic conversion
let conversion = convert_to_pdf_a(&mut doc, level)?;
println!("{} actions taken", conversion.actions.len());
// Step 3: Re-validate
let result = validate_pdf_a(&mut doc, level)?;
if result.has_errors() {
println!("{} errors remain after conversion:", result.errors.len());
for e in &result.errors {
println!(" {} -- {}", e.code, e.message);
}
} else {
println!("Document is now PDF/A-2b compliant");
}
PdfALevel-Methoden
Die Enumeration PdfALevel enthält Hilfsmethoden zur Abfrage der Fähigkeiten einer Stufe:
| Methode | Rückgabe | Beschreibung |
|---|---|---|
part() |
PdfAPart |
Teil der ISO 19005 (Part1, Part2, Part3) |
conformance() |
char |
Konformitätsbuchstabe (‘a’, ‘b’ oder ‘u’) |
requires_structure() |
bool |
Ob ein getaggter Strukturbaum verpflichtend ist |
requires_unicode() |
bool |
Ob eine Unicode-Zuordnung verpflichtend ist |
allows_transparency() |
bool |
Ob Transparenz zulässig ist |
allows_jpeg2000() |
bool |
Ob JPEG-2000-Bilder zulässig sind |
allows_embedded_files() |
bool |
Ob Dateianhänge zulässig sind |
xmp_part() |
&str |
Wert von XMP pdfaid:part |
xmp_conformance() |
&str |
Wert von XMP pdfaid:conformance |
from_xmp(part, conformance) |
Option<Self> |
Parst die Stufe aus XMP-Metadatenwerten |
Nächste Schritte
- PDF/UA-Barrierefreiheit – Validierung der Barrierefreiheit
- PDF/X-Druckproduktion – Validierung für die Druckproduktion
- API-Referenz – vollständige Rust-API