Skip to content

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:

  1. Einfügen von XMP-Metadaten – fügt die Einträge pdfaid:part und pdfaid:conformance hinzu
  2. Schrifteinbettung – bettet alle referenzierten, aber nicht eingebetteten Schriften ein
  3. Entfernen von JavaScript – entfernt JavaScript-Aktionen und -Trigger
  4. Reduzieren der Transparenz – rendert transparente Elemente als undurchsichtig (nur PDF/A-1)
  5. ICC-Profil-Konvertierung – wandelt geräteabhängige Farben in ICC-basierte Farbräume um
  6. 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