A PDFlibPas a beágyazott fájlokat nem a dokumentum egészéhez, hanem egy konkrét oldalhoz rendeli hozzá: /AF tömböt ír az oldal szótárába, miközben maga a tartalom a dokumentum EmbeddedFiles névfájában marad bejegyezve. Ezt a kettéválasztást írja le az ISO 32000-2 §14.13, és ez az, amivel az olvasó meg tudja válaszolni azt a kérdést, amelyre egy dokumentumszintű melléklet nem tud válaszolni: melyik oldalhoz tartozik ez az adat
A felhasználási esetek specifikusabbak az általános mellékleteknél. Egy felmérési jelentés, amelyben minden oldal viseli a grafikonja mögötti nyers mérési sorozatot. Egy szkennelt tétel, ahol minden oldal őrzi a szövegrétegét előállító OCR eredményt. Egy rajzkészlet, ahol minden lap viseli azt a CAD kivonatot, amelyből megrajzolták. Minden esetben egy dokumentumszintű mellékletlista fájlok halmaza volna, amelyeknek a nevei oldalszámokat kódolnak, és ez konvenció, nem struktúra
Egy tartalom, két hivatkozási hely
A fontos szerkezeti pont az, hogy az oldalszintű társítás semmiről sem készít második példányt. A fájl egyszer van beágyazva, és pontosan úgy van bejegyezve az EmbeddedFiles névfában, ahogy egy dokumentumszintű melléklet, ugyanazzal a fájlspecifikációs gépezettel. Az különbözik, hogy a hivatkozás és a kapcsolati kulcsa hova kerül: az oldal szótárába a dokumentum katalógusa helyett
Két következménye van. Az első, hogy egy olyan olvasó, amely csak a dokumentumszintű mellékleteket ismeri, továbbra is megtalálja a tartalmat, mert ott van a névfában, ahová az ilyen olvasó néz. A második, hogy az oldaltársítás törlése a kötést szünteti meg, nem a fájlt. A ClearPageAssociatedFiles leválasztja az oldalt a társított fájljairól, és a tartalmak elérhetők maradnak a névfán keresztül, ez a konzervatív viselkedés: egy művelet, amely azt mondja, töröld a társítást, nem semmisíthet meg csendben olyan adatokat, amelyekre a dokumentum más része hivatkozhat
Ennek a függvénynek egy szándékosan szűk sikerfeltétele van, érdemes ismerni. Csak akkor jelent sikert, ha az oldal ténylegesen viselt /AF kulcsot. A soha nem társított oldal hibát ad vissza, nem vidám megerősítést, tehát a hívó nem tévesztheti össze a tétlen működést a befejezett takarítással
var
Lib: TPDFlib;
Idx, I: Integer;
begin
Lib := TPDFlib.Create(nil);
try
Lib.LoadFromFile('survey-report.pdf');
// Hozzárendeli a 3. oldal grafikonját előállító mérési sorozatot
Idx := Lib.AddPageAssociatedFileFromFile(3,
'series-03.csv', // fájl a lemezen
'measurements.csv', // megjelenített név a PDF-en belül
'text/csv', // MIME típus
'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;
A kapcsolati sztring a gyakorlatban nem szabad szöveg. Az ISO 32000-2 egy szókincset definiál: Source, Data, Alternative, Supplement, EncryptedPayload, FormData, Schema és Unspecified, és a fogyasztók ehhez igazodnak. Data a grafikon mögötti számokhoz, Source ahhoz a dokumentumhoz, amelyből az oldal készült, Alternative egy ekvivalens ábrázoláshoz. Válasszon a szókincsből akkor is, ha a folyamata még semmi nem olvassa, mert a lánc következő eszköze esetleg igen
Miért kell ugyanannak a keresésnek FollowRef mindkét irányban?
Mert a hivatkozáskövetés két különböző kérdésre válaszol, és a kódnak tudnia kell, melyiket teszi fel. A közvetett hivatkozásokat követő kulcskeresés azt az objektumot adja vissza, amelyre a hivatkozás mutat. A nem követő keresés magát a hivatkozást adja vissza. Mindkettő helyes, és a rossz használata csendes félreműködést ad, nem hibát
Egy társított fájl kiolvasása az első irányt mutatja. Hogy megkapja a fájlspecifikáció /EF és /F kulcsai mögötti beágyazott stream objektumszámát, a keresésnek nem szabad követnie, mert a követés a hivatkozást stream objektummá oldja fel, és az objektumszám odaveszik. A szabály általánosítható: minden olyan kódút, amely objektumtartalom helyett objektumidentitást igényel, a nyers hivatkozást kell elfogadnia
Az opcionális tartalom az ellenkező irányt mutatja, és többe került megtalálni. Az opcionális tartalom tulajdonságszótára közvetett objektumként kerül a katalógusba, tehát az azt visszaolvasó kód követés nélkül hivatkozást kap, nem szótárat. Az értéken végzett típusellenőrzés elbukik, és a kézenfekvő tartalék ág, ha nincs konfiguráció, csinál egyet, lefut és felülírja a már ott lévő konfigurációt. Semmi nem dob kivételt. A opcionális tartalomcsoportok és rétegek cikkben leírt rétegek egyszerűen elveszítik az alapértelmezett láthatósági állapotukat
A tanulság mindkét eseten túl általánosítható. Amikor egy keresés hivatkozást vagy objektumot is adhat vissza, a csupasz típusellenőrzés nem hibakezelés: egy ág, amely előbb-utóbb rossz okból teljesül. Döntse el explicit módon, hogy minden hívási helynek mire van szüksége, és részesítse előnyben azt a publikus API-t, amely közvetlenül válaszol a kérdésre, például egy opcionális tartalom darabszám tulajdonságot, a katalógus szótárát védett accessorból kibányászása helyett
// A dokumentumszintű mellékletek és az oldalszintű társítások együtt élnek.
// Egy beágyazott fájlt dokumentumszinten is meg lehet jelölni társítottként
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));
// A törlés leválasztja az oldal kötését; a tartalom a névfában marad
if Lib.ClearPageAssociatedFiles(3) > 0 then
Writeln('page 3 associations removed, payloads still reachable');
Mit tesznek a megfelelőségi módok a mellékletekkel?
Az archiválási profilok korlátozzák, mi ágyazható be, és a korlátozás a belépési pontnál érvényesül, nem mentéskor. A PDF/A-1 teljesen tiltja a beágyazott fájlokat, a PDF/A-2 csak beágyazott PDF/A dokumentumokat enged, a PDF/A-3 pedig az a profil, amely megnyitotta a beágyazást tetszőleges fájltípusok felé, és pontosan ezért épülnek rá a hibrid számlaformátumok
A PDFlibPas akkor utasítja el a mellékletet, ha az aktív megfelelőségi mód nem engedi, a hívásnál, nem pedig több száz művelettel később a kimenet alatt. Ez tudatos döntés arról, hol a legolcsóbb hibára reagálni: a hívási helyen kapott elutasítás megnevezi a fájlt, amelyet épp hozzáadott, míg a mentéskori elutasítás egy dokumentumot nevez meg, és ráhagyja, hogy kitalálja, a negyven melléklet melyik okozta
Ez az oka annak is, hogy a társított fájlok olyan gyakran tűnnek fel az elektronikus számlázásban. Egy hibrid számla egy PDF, amelyet az ember olvas, és amelyhez géppel olvasható XML tartalom van csatolva a megfelelő kapcsolattal megjelölve, és mind a konténer profil, mind a kapcsolati kulcs a specifikáció része, nem konvenció. Ezt a felépítést a Factur-X és ZUGFeRD hibrid számlák építése tárgyalja, a metaadati oldalt pedig a PDF/A-3 XMP bővítményséma fedi le
Mikor legyen a társítás oldalonként, dokumentumonkénti helyett?
Akkor, amikor a fogyasztónak tudnia kell, melyik oldalhoz tartozik az adat, és csak akkor. A dokumentumszintű mellékletek egyszerűbbek, a megjelenítők szélesebb körben támogatják őket, és elegendők minden alkalommal, amikor a tartalom a teljes dokumentumot írja le: egy számla XML, egy aláírás-jegyzék, egy forrásarchívum. Oldalszintű társításhoz akkor nyúljon, ha a tartalom valóban oldalhatókörű, és az oldalidentitás része a jelentésének
A támogatottság a gyakorlati korlát. Az oldalszintű társított fájlok PDF 2.0 szerkezetek, és a megjelenítői támogatásuk vékonyabb, mint a dokumentumszintű mellékletekhez. Mivel a tartalom így vagy úgy a névfában ül, az oldalakon az /AF-et figyelmen kívül hagyó megjelenítő is mutatja a fájlt a mellékletlistájában, tehát a leromlás kecses. De ha az oldal kötése a fogyasztójának lényeges, nem csupán hasznos metaadat, ellenőrizze azt az olvasót, amelyet ténylegesen céloz, feltételezés helyett
Az oldalszintű társított fájlok, a dokumentumszintű mellékletek és mindkettőt irányító archiválási profil kapuk a PDFlibPas Delphi PDF könyvtárban érhetők el. Ha közben régebbi fájlokat is javít bejövő oldalon, az PDF/A-ra konvertálás metaadatjavítással cikk metaadati és megfelelőségi munkája dönti el először, hogy e mellékletutak közül melyik áll egyáltalán rendelkezésére