Jak pracovat s PDF daty v Python

Jak pracovat s PDF daty v Python

Aspose.PDF FOSS pro Python představuje XMP metadata PDF dokumentu jako model dat v paměti postavený na objektech XmpPacket, XmpField, XmpArray, XmpStruct a XmpProperty, přičemž NamespaceProvider mapuje prefixy jmenných prostorů na URI. To vám umožní číst, vytvářet a přepisovat strukturovaná metadata — tituly, data, seznamy klíčových slov, vlastní pole — bez ručního psaní RDF/XML. Knihovna je čistý Python a je nainstalována pomocí níže uvedeného příkazu.

Průvodce krok za krokem

Krok 1: Nainstalujte balíček

Nainstalujte FOSS balíček Aspose.PDF:

git clone https://github.com/aspose-pdf-foss/Aspose-PDF-FOSS-for-Python.git
cd Aspose-PDF-FOSS-for-Python
pip install -e .

Ověřte instalaci importováním XmpPacket a vytištěním potvrzovací zprávy:

from aspose_pdf import XmpPacket
print("aspose-pdf-foss-for-python is ready.")

Krok 2: Naimportujte požadované třídy

Importujte třídy modelu dat XMP a řešitel jmenných prostorů:

from aspose_pdf import (
    NamespaceProvider,
    XmpArray,
    XmpField,
    XmpPacket,
    XmpProperty,
    XmpStruct,
)

Krok 3: Vytvořte paket a nastavte jednoduché vlastnosti

XmpPacket() začíná s prázdným seznamem polí. set_value(prefix, name, value, uri=...) nastaví nebo nahradí jednoduchou vlastnost a get(prefix_or_uri, name) ji načte zpět jako XmpField; get přijímá buď registrovaný prefix, nebo úplnou URI jmenného prostoru:

from aspose_pdf import XmpPacket

packet = XmpPacket()
packet.set_value("dc", "title", "Quarterly Report")
packet.set_value(
    "dc", "creator", "Automation Pipeline",
    uri="http://purl.org/dc/elements/1.1/",
)

title_field = packet.get("dc", "title")
print(title_field.value)  # "Quarterly Report"

Krok 4: Uložte typované hodnoty

XmpPacket poskytuje typované pohodlné přístupové metody, které převádějí do a z čistého textového formátu, který XMP interně ukládá: set_date/get_date, set_int/get_int, set_real/get_real a set_bool/get_bool. Každý getter vrací None, když je vlastnost nepřítomna, místo vyvolání výjimky:

from datetime import datetime

packet.set_date("xmp", "CreateDate", datetime(2026, 7, 29, 9, 30))
packet.set_int("pdf", "PageCount", 42)
packet.set_real("custom", "ConfidenceScore", 0.97, uri="https://example.com/ns/custom/1.0/")
packet.set_bool("custom", "IsFinal", True, uri="https://example.com/ns/custom/1.0/")

print(packet.get_date("xmp", "CreateDate"))
print(packet.get_int("pdf", "PageCount"))
print(packet.get_real("custom", "ConfidenceScore"))
print(packet.get_bool("custom", "IsFinal"))

Krok 5: Uložte lokalizovaný text a uspořádané pole

set_localized_text zapisuje jazykově alternativní (rdf:Alt) vlastnost, například dc:title, v konkrétním jazyce, výchozí je "x-default". set_array zapisuje uspořádané (Seq), neuspořádané (Bag) nebo alternativní (Alt) pole z obyčejného seznamu hodnot a get_array jej načte zpět jako seznam řetězců:

packet.set_localized_text("dc", "description", "Quarterly summary", lang="en")
packet.set_localized_text(
    "dc", "description", "Resumen trimestral",
    uri="http://purl.org/dc/elements/1.1/", lang="es",
)
print(packet.get_localized_text("dc", "description", lang="es"))

packet.set_array("dc", "subject", ["finance", "quarterly", "internal"], kind="Bag")
print(packet.get_array("dc", "subject"))

Krok 6: Vytvořit strukturované hodnoty pomocí XmpStruct

Některé vlastnosti XMP (záznamy rozměrů, položky historie) jsou strukturované hodnoty, nikoli jednoduchý text. Vytvořte jednu pomocí XmpStruct, přidejte objekt XmpField s add, přečtěte člen zpět podle názvu pomocí get a poté připojte strukturu k paketu pomocí add:

dimensions = XmpStruct()
dimensions.add(XmpField(prefix="stDim", name="w", value="612"))
dimensions.add(XmpField(prefix="stDim", name="h", value="792"))
dimensions.add(XmpField(prefix="stDim", name="unit", value="pt"))

print(dimensions.get("w").value)  # "612"

packet.add(XmpField(prefix="xmpTPg", name="MaxPageSize", value=dimensions))

Krok 7: Zaregistrovat vlastní jmenné prostory XMP

NamespaceProvider je přednačtený se standardními jmennými prostory XMP (Dublin Core, Adobe XMP, PDF a další). Zavolejte register(prefix, uri) pro přidání vlastního mapování — vrací samotného poskytovatele, takže volání lze řetězit — a poté připojte poskytovatele k paketu, aby serializace mohla převést vlastní prefix na jeho URI:

from aspose_pdf import NamespaceProvider, XmpPacket

provider = NamespaceProvider()
provider.register("custom", "https://example.com/ns/custom/1.0/")

packet = XmpPacket(namespace_provider=provider)
packet.set_value("custom", "batch_id", "run-2026-07-29")

Krok 8: Analyzovat a serializovat paket

XmpPacket.parse(data, provider=...) načte surová data nebo text XMP paketu do XmpPacket. serialize() a to_bytes() oba převádějí paket zpět na bajty XMP paketu:

xmp_bytes = packet.to_bytes()

restored = XmpPacket.parse(xmp_bytes)
print(restored.get("dc", "title").value)

Časté problémy a opravy

get() nebo typovaný getter vrací None i když jsem právě nastavil vlastnost

Potvrďte, že argument prefix (nebo URI) pro get/get_int/get_date/etc. přesně odpovídá tomu, co bylo předáno odpovídajícímu volání set_* — get porovnává jak předponu pole, tak jeho URI jmenného prostoru, ale nesouladná vlastní předpona v jednom volání a URI v druhém bude chybět.

Vlastní předpona jmenného prostoru produkuje neúplný výstup při serializaci

Předpona, která není jednou ze standardních XMP jmenných prostorů (dc, xmp, pdf a podobně), vyžaduje buď explicitní argument uri= u každého volání set_*, nebo NamespaceProvider s touto předponou zaregistrovanou a připojenou k paketu pomocí XmpPacket(namespace_provider=provider) před voláním serialize()/to_bytes().

get_bool, get_int, nebo get_real returns None pro hodnotu, o které vím, že je nastavena

Tyto typované gettery vrací None, když uložený text nelze rozparsovat jako očekávaný typ — například get_int u vlastnosti, jejíž hodnota byla nastavena pomocí set_value jako volný text místo set_int. Použijte odpovídající typovaný setter (set_int, set_real, set_bool), aby parsingová logika getteru odpovídala zápisové cestě.

XmpPacket.parse raises ValueError na paketu z nedůvěryhodného zdroje

parse odmítá jakékoli deklarace <!DOCTYPE nebo <!ENTITY jako obranu proti nepřátelskému vstupu proti útokům XXE a billion-laughs. Legitimní XMP paket nikdy nepotřebuje DTD; považujte výjimku za signál, že zdrojový stream je poškozený nebo nebezpečný, místo obcházení této ochrany.

get_array returns None namísto seznamu

get_array vrací None, když pojmenovaná vlastnost buď neexistuje, nebo nebyla uložena jako XmpArray (například pokud byla nastavena pomocí set_value místo set_array). Použijte set_array při zápisu vlastnosti, aby uložená hodnota odpovídala tvaru, který očekává get_array.

Často kladené otázky

Jaký je rozdíl mezi set_value a typovanými nastaviteli jako set_int?

set_value ukládá cokoliv, co value předáte, tak jak je. Typované nastaviteli (set_date, set_int, set_real, set_bool) převádějí jejich vstup do prostého textového formátu, který XMP interně používá, a jsou spárovány s odpovídajícím typovaným getterem, který jej znovu rozparsuje, takže je používejte, když potřebujete bezpečnost typu při obousměrném převodu místo surových řetězců.

Jak se liší druhy XmpArray (Bag, Seq, Alt)?

Bag je neuspořádaná množina hodnot, Seq je uspořádaný seznam a Alt obsahuje alternativní hodnoty (nejčastěji jazykové alternativy, jak používá set_localized_text). Předávejte požadovaný typ do set_array(..., kind="Bag") nebo vytvořte XmpArray(kind=...) přímo.

Mohu přečíst surový seznam vlastností v paketu, aniž bych předem znal jejich názvy?

Ano — iterujte packet.fields, který obsahuje každý XmpField, XmpArray a XmpProperty přidaný do paketu v pořadí vložení.

Potřebuji NamespaceProvider pro standardní XMP jmenné prostory?

Ne. dc, xmp, pdf a ostatní standardní předpony se vyřeší automaticky. NamespaceProvider je potřeba jen pro vlastní předpony, které si vymyslíte.

Jak se XmpProperty kvalifikátory liší od prostého XmpField?

XmpProperty obaluje základní XmpField spolu se seznamem kvalifikačních polí (přidaných pomocí add_qualifier), používaných pro vzácnější případ, kdy samotná vlastnost potřebuje další RDF metadata připojená k její hodnotě, nad rámec xml:lang kvalifikátoru, který již XmpField.language pokrývá.

Viz také:

 Čeština