PDFlibPas, gömülü bir dosyayı belgenin bütününe değil belirli tek bir sayfaya bağlar; /AF dizisini sayfa sözlüğüne yazarken veri paketinin kendisi belgenin EmbeddedFiles ad ağacında kayıtlı kalır. Bu ayrım, ISO 32000-2 §14.13'ün tarif ettiği şeydir ve bir okuyucunun belge düzeyi ekin cevaplayamadığı soruya cevap vermesini sağlar: bu veri hangi sayfaya aittir
Kullanım senaryoları genel amaçlı eklere göre daha özeldir. Her sayfasının, grafiğinin arkasındaki ham ölçüm serisini taşıdığı bir saha araştırması raporu. Her sayfanın, metin katmanını üreten OCR sonucunu sakladığı taranmış bir parti. Her yaprağın, kendisinin render edildiği CAD çıkarımını taşıdığı bir çizim seti. Bunların her birinde belge düzeyi bir ek listesi, adlarına sayfa numarası gömdürülmüş bir dosya yığını olur; bu bir yapı değil, bir konvansiyondur
Tek veri paketi, referans verilen iki yer
Önemli yapısal nokta şu: sayfa düzeyi ilişkilendirme hiçbir şeyin ikinci bir kopyasını oluşturmaz. Dosya bir kez gömülür ve bir belge düzeyi ek gibi, aynı file specification mekanizmasıyla EmbeddedFiles ad ağacına kaydedilir. Farklı olan, referansın ve ilişki anahtarının nereye yazıldığıdır: belge kataloğu yerine sayfa sözlüğüne
Bunun iki sonucu var. Birincisi, yalnızca belge düzeyi ekleri bilen bir okuyucu veri paketini yine bulur; çünkü paket, söz konusu okuyucunun baktığı ad ağacındadır. İkincisi, sayfa ilişkilendirmesini temizlemek bağı kaldırır, dosyayı değil. ClearPageAssociatedFiles sayfayı ilişkili dosyalarından ayırır ve veri paketlerini ad ağacı üzerinden erişilebilir bırakır; bu muhafazakar davranıştır: ilişkilendirmeyi temizle diyen bir işlem, belgenin başka bir bölümünün referans verebileceği veriyi sessizce yok etmemelidir
İşlevin bilinmeye değer, kasıtlı olarak dar bir başarı koşulu var. Yalnızca sayfada gerçekten bir /AF anahtarı varken başarı bildirir. Hiç ilişkilendirme almamış bir sayfa, neşeli bir onay yerine başarısızlık döndürür; böylece çağıran, no-op bir çağrıyı tamamlanmış bir temizlik sanamaz
var
Lib: TPDFlib;
Idx, I: Integer;
begin
Lib := TPDFlib.Create(nil);
try
Lib.LoadFromFile('survey-report.pdf');
// 3. sayfadaki grafiği üreten ölçüm serisini iliştir
Idx := Lib.AddPageAssociatedFileFromFile(3,
'series-03.csv', // diskteki dosya
'measurements.csv', // PDF içindeki görünen ad
'text/csv', // MIME türü
'Raw measurement series for figure 3',
'Data'); // AFRelationship, ISO 32000-2 14.13
if Idx < 0 then
raise Exception.Create('page association refused');
for I := 0 to Lib.GetPageAssociatedFileCount(3) - 1 do
Writeln('page 3 associated file, embedded index ',
Lib.GetPageAssociatedFileEmbeddedIndex(3, I));
Lib.SaveToFile('survey-report-with-data.pdf');
finally
Lib.Free;
end;
end;
İlişki dizgesi pratikte serbest metin değildir. ISO 32000-2 bir söz dağarı tanımlar: Source, Data, Alternative, Supplement, EncryptedPayload, FormData, Schema ve Unspecified; tüketiciler buna göre konumlanır. Bir grafiğin arkasındaki sayılar için Data, bir sayfanın üretildiği belge için Source, eşdeğer bir temsil için Alternative. İşlem hattınızda henüz okuyan hiçbir şey olmasa da söz dağarından seçin; çünkü zincirdeki bir sonraki araç okuyor olabilir
Aynı arama neden her iki yönde de FollowRef ister?
Çünkü referans takibi iki farklı soruya cevap verir ve kod, hangisini sorduğunu bilmek zorundadır. Dolaylı referansları takip eden bir anahtar araması, referansın işaret ettiği nesneyi döndürür. Takip etmeyen bir arama ise referansın kendisini döndürür. İkisi de doğrudur ve yanlışını kullanmak hata değil, sessiz bir yanlış davranış üretir
İlişkili bir dosyayı okumak ilk yönü gösterir. File specification'ın /EF ve /F anahtarlarının arkasındaki gömülü akışın nesne numarasını elde etmek için aramanın takip memesi gerekir; çünkü takip, referansı akış nesnesine çözümler ve nesne numarası kaybolur. Kural geneller: nesne içeriği değil nesne kimliği gerektiren her kod yolu ham referansı almak zorundadır
Optional content ters yönü gösterir ve onu bulmak daha çok maliyet çıkardı. Optional content properties sözlüğü kataloğa dolaylı nesne olarak yazılır; bu yüzden takip etmeden geri okuyan kod, sözlük yerine bir referans alır. O değer üzerindeki tip kontrolü ardından başarısız olur ve doğal fallback dalı, yapılandırma yoksa bir tane oluştur, çalışıp zaten orada duran yapılandırmayı üzerine yazar. Hiçbir şey fırlatmaz. Optional content groups ve katmanlar makalesinde anlatılan katmanlar, varsayılan görünürlük durumlarını yalnızca kaybeder
Ders her iki vakanın da ötesine geneller. Bir arama, referans da nesne de döndürebilecekken sade bir tip kontrolü hata yönetimi değildir: sonunda yanlış gerekçeyle seçilecek bir daldır. Her çağrı noktasının neye ihtiyacı olduğunu açıkça belirleyin ve katalog sözlüğü için korumalı bir accessor'a uzanmak yerine soruyu doğrudan cevaplayan public API'yi tercih edin; örneğin bir optional-content sayacı özelliğini
// Belge düzeyi ekler ile sayfa düzeyi ilişkilendirmeler bir arada
// yaşar. Bir gömülü dosya belge düzeyinde de ilişkili işaretlenebilir
if Lib.IsEmbeddedFileAssociated(0) = 0 then
Lib.SetEmbeddedFileAssociated(0, 1, 'Supplement');
Writeln('document associated files: ', Lib.GetAssociatedFileCount);
Writeln('page 3 associated files : ',
Lib.GetPageAssociatedFileCount(3));
// Temizleme, sayfa bağını ayırır; veri paketi ad ağacında kalır
if Lib.ClearPageAssociatedFiles(3) > 0 then
Writeln('page 3 associations removed, payloads still reachable');
Conformance modlarının eklere yaptığı
Arşiv profilleri neyin gömülebileceğini kısıtlar ve kısıt, kayıt zamanında değil giriş noktasında uygulanır. PDF/A-1 gömülü dosyaları tümüyle yasaklar, PDF/A-2 yalnızca gömülü PDF/A belgelerine izin verir, PDF/A-3 ise gömmeyi rastgele dosya türlerine açan profildir; hibrit fatura formatlarının üzerine kurulduğu da tam olarak budur
PDFlibPas, aktif conformance modu izin vermediğinde eki reddeder; çağrı sırasında, yüzlerce işlem sonra çıktı sırasında değil. Bu, hatanın en ucuz işlem gördüğü yer hakkında bilinçli bir tercihtir: çağrı noktasındaki red, eklemekte olduğunuz dosyayı adıyla bildirir; kayıt zamanındaki red ise bir belgeyi adıyla bildirir ve sorunun kırk ekten hangisinden kaynaklandığını sizin çözmenizi bekler
İlişkili dosyaların elektronik faturalamada bu kadar sık görünmesinin nedeni de bu. Hibrit bir fatura; insanın okuduğu, makine okunur XML veri paketi iliştirilmiş ve doğru ilişkiyle işaretlenmiş bir PDF'tir; hem kapsayıcı profil hem ilişki anahtarı konvansiyon değil, spesifikasyonun parçasıdır. Bu kurgu Factur-X ve ZUGFeRD hibrit faturaları oluşturma makalesinde, metadata tarafı ise PDF/A-3 XMP extension şeması makalesinde ele alınır
İlişkilendirme belge başına değil sayfa başına ne zaman olmalı?
Bir tüketicinin verinin hangi sayfaya ait olduğunu bilmesi gerektiğinde ve yalnızca o zaman. Belge düzeyi ekler daha basittir, görüntüleyicilerde daha yaygın desteklenir ve veri paketi bütün belgeyi tarif ettiği sürece yeterlidir: bir fatura XML'i, bir imza manifestosu, bir kaynak arşivi. Sayfa düzeyi ilişkilendirmeye, veri paketi gerçekten sayfa kapsamlıyken ve sayfa kimliği anlamının parçasıyken başvurun
Destek, pratikte kısıt olan taraftır. Sayfa düzeyi ilişkili dosyalar bir PDF 2.0 kurulumudur ve görüntüleyici desteği belge düzeyi eklere göre daha zayıftır. Veri paketi her durumda ad ağacında durduğu için, sayfalardaki /AF'i yok sayan bir görüntüleyici dosyayı yine ek listesinde gösterir; bozulma düzgündür. Ama sayfa bağı tüketiciniz için faydalı bir metadata değil zorunluluksa, varsaymak yerine gerçekten hedeflediğiniz okuyucuyu doğrulayın
Sayfa düzeyi ilişkili dosyalar, belge düzeyi ekler ve ikisini de yöneten arşiv profili kapıları, PDFlibPas Delphi PDF kütüphanesi ile birlikte gelir. Girişte eski dosyaları da onarıyorsanız, metadata onarımıyla PDF/A'ya dönüştürme makalesindeki metadata ve conformance çalışası, bu ek yollarından hangilerinin baştan elinizin altında olduğunu belirleyendir