Cara Bekerja dengan Data PDF di Python
Aspose.PDF FOSS untuk Python merepresentasikan metadata XMP dokumen PDF sebagai model data dalam memori yang dibangun dari objek XmpPacket, XmpField, XmpArray, XmpStruct, dan XmpProperty, dengan NamespaceProvider yang menyelesaikan prefiks namespace menjadi URI. Ini memungkinkan Anda membaca, membuat, dan menulis ulang metadata terstruktur — judul, tanggal, daftar kata kunci, bidang khusus — tanpa menulis secara manual RDF/XML. Perpustakaan ini murni Python dan diinstal dengan perintah di bawah.
Panduan Langkah demi Langkah
Langkah 1: Instal Paket
Instal paket Aspose.PDF FOSS:
git clone https://github.com/aspose-pdf-foss/Aspose-PDF-FOSS-for-Python.git
cd Aspose-PDF-FOSS-for-Python
pip install -e .Verifikasi instalasi dengan mengimpor XmpPacket dan mencetak pesan konfirmasi:
from aspose_pdf import XmpPacket
print("aspose-pdf-foss-for-python is ready.")Langkah 2: Impor Kelas yang Diperlukan
Impor kelas model data XMP dan resolver namespace:
from aspose_pdf import (
NamespaceProvider,
XmpArray,
XmpField,
XmpPacket,
XmpProperty,
XmpStruct,
)Langkah 3: Buat Packet dan Atur Properti Sederhana
XmpPacket() memulai dengan daftar bidang kosong. set_value(prefix, name, value, uri=...) mengatur atau mengganti properti sederhana, dan get(prefix_or_uri, name) membacanya kembali sebagai XmpField; get menerima baik prefiks terdaftar maupun URI namespace lengkap:
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"Langkah 4: Simpan Nilai Bertipe
XmpPacket menyediakan aksesori kenyamanan bertipe yang mengonversi ke dan dari bentuk teks polos yang disimpan XMP secara internal: set_date/get_date, set_int/get_int, set_real/get_real, dan set_bool/get_bool. Setiap getter mengembalikan None ketika properti tidak ada alih-alih melempar:
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"))Langkah 5: Simpan Teks Terlokalisasi dan Array Berurutan
set_localized_text menulis properti alternatif bahasa (rdf:Alt) seperti dc:title dalam bahasa tertentu, dengan default "x-default". set_array menulis array berurutan (Seq), tidak berurutan (Bag), atau alternatif (Alt) dari daftar nilai polos, dan get_array membacanya kembali sebagai daftar string:
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"))Langkah 6: Bangun Nilai Terstruktur dengan XmpStruct
Beberapa properti XMP (rekaman dimensi, entri riwayat) merupakan nilai terstruktur bukan teks sederhana. Buat satu dengan XmpStruct, tambahkan anggota XmpField objek dengan add, dan baca kembali anggota tersebut berdasarkan nama dengan get, lalu lampirkan struct ke paket dengan 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))Langkah 7: Daftarkan Namespace XMP Kustom
NamespaceProvider telah dimuat sebelumnya dengan namespace XMP standar (Dublin Core, Adobe XMP, PDF, dan lainnya). Panggil register(prefix, uri) untuk menambahkan pemetaan kustom — ia mengembalikan penyedia itu sendiri sehingga pemanggilan dapat dirantai — lalu lampirkan penyedia ke paket agar serialisasi dapat menyelesaikan awalan kustom ke URI-nya:
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")Langkah 8: Mengurai dan Menyerialkan Paket
XmpPacket.parse(data, provider=...) membaca byte atau teks paket XMP mentah ke dalam XmpPacket. serialize() dan to_bytes() keduanya menghasilkan paket kembali menjadi byte paket XMP:
xmp_bytes = packet.to_bytes()
restored = XmpPacket.parse(xmp_bytes)
print(restored.get("dc", "title").value)Masalah Umum dan Solusinya
get() atau getter bertipe mengembalikan None meskipun saya baru saja menyetel properti
Pastikan argumen prefix (atau URI) ke get/get_int/get_date/dll. cocok persis dengan apa yang diberikan ke pemanggilan set_* yang sesuai — get mencocokkan baik prefiks bidang maupun URI namespace-nya, tetapi prefiks khusus yang tidak cocok pada satu pemanggilan dan URI pada yang lain akan terlewat.
Prefiks namespace khusus menghasilkan output tidak lengkap saat diserialisasi
Prefiks yang bukan termasuk dalam namespace XMP standar (dc, xmp, pdf, dan sejenisnya) memerlukan baik argumen uri= eksplisit pada setiap pemanggilan set_*, atau NamespaceProvider dengan prefiks tersebut terdaftar dan dilampirkan ke paket melalui XmpPacket(namespace_provider=provider) sebelum memanggil serialize()/to_bytes().
get_bool, get_int, atau get_real returns None untuk nilai yang saya tahu telah disetel
Getter yang bertipe ini mengembalikan None ketika teks yang disimpan tidak dapat diurai sebagai tipe yang diharapkan — misalnya, get_int pada properti yang nilainya diatur dengan set_value sebagai teks bebas alih-alih set_int. Gunakan setter yang bertipe sesuai (set_int, set_real, set_bool) agar logika penguraian getter cocok dengan jalur penulisan.
XmpPacket.parse raises ValueError pada paket dari sumber yang tidak terpercaya
parse menolak setiap deklarasi <!DOCTYPE atau <!ENTITY sebagai perlindungan masukan bermusuhan terhadap serangan XXE dan billion-laughs. Paket XMP yang sah tidak pernah memerlukan DTD; anggap pengecualian tersebut sebagai sinyal bahwa aliran sumber rusak atau tidak aman alih-alih mencoba mengakali perlindungan.
get_array returns None daripada daftar
get_array mengembalikan None ketika properti yang dinamai tidak ada atau tidak disimpan sebagai XmpArray (misalnya, jika diatur dengan set_value alih-alih set_array). Gunakan set_array saat menulis properti sehingga nilai yang disimpan cocok dengan bentuk yang diharapkan get_array.
Pertanyaan yang Sering Diajukan
Apa perbedaan antara set_value dan setter bertipe seperti set_int?
set_value menyimpan apa pun value yang Anda berikan apa adanya. Setter bertipe (set_date, set_int, set_real, set_bool) mengonversi masukan mereka ke bentuk teks polos yang digunakan XMP secara internal dan dipasangkan dengan getter bertipe yang cocok yang mengurai kembali, jadi gunakan mereka ketika Anda membutuhkan keamanan tipe round-trip daripada string mentah.
Bagaimana perbedaan jenis XmpArray (Bag, Seq, Alt)?
Bag adalah himpunan nilai yang tidak berurutan, Seq adalah daftar berurutan, dan Alt menyimpan nilai alternatif (sering kali alternatif bahasa, seperti yang digunakan oleh set_localized_text). Kirimkan jenis yang diinginkan ke set_array(..., kind="Bag") atau bangun XmpArray(kind=...) secara langsung.
Bisakah saya membaca daftar mentah properti pada paket tanpa mengetahui namanya terlebih dahulu?
Ya — iterasikan packet.fields, yang menyimpan setiap XmpField, XmpArray, dan XmpProperty yang ditambahkan ke paket dalam urutan penyisipan.
Apakah saya memerlukan NamespaceProvider untuk namespace XMP standar?
Tidak. dc, xmp, pdf, dan prefiks standar lainnya diselesaikan secara otomatis. NamespaceProvider hanya diperlukan untuk prefiks kustom yang Anda buat sendiri.
Bagaimana qualifier XmpProperty berbeda dari XmpField biasa?
XmpProperty membungkus XmpField dasar bersama dengan daftar bidang qualifier (ditambahkan dengan add_qualifier), digunakan untuk kasus yang lebih jarang di mana suatu properti sendiri memerlukan metadata RDF tambahan yang dilampirkan pada nilainya, di luar qualifier xml:lang yang sudah dicakup oleh XmpField.language.