PDFlibPas kiinnittää upotetun tiedoston yhteen tiettyyn sivuun koko dokumentin sijaan kirjoittamalla /AF-taulukon sivusanakirjaan, kun taas itse sisältö pysyy rekisteröitynä dokumentin EmbeddedFiles-nimipuussa. Juuri tuon jaon ISO 32000-2 §14.13 kuvaa, ja se on se, mikä antaa lukijalle mahdollisuuden vastata kysymykseen, johon dokumenttitason liite ei pysty: mille sivulle tämä data kuuluu
Käyttötapaukset ovat tarkempia kuin yleiset liitteet. Kartoitusraportti, jossa jokainen sivu kantaa kaavionsa takana olevan raakamittaussarjan. Skannattu erä, jossa jokainen sivu säilyttää tekstikerroksensa tuottaneen OCR-tuloksen. Piirustuskokoelma, jossa jokainen taulu kantaa CAD-oteversion, josta se renderöitiin. Kussakin tapauksessa dokumenttitason liiteluettelo olisi pino tiedostoja, joiden nimet koodaavat sivunumeroita, eli konventio rakenteen sijaan
Yksi sisältö, kaksi paikkaa, joista siihen viitataan
Rakenteellisesti tärkeä pointti on, ettei sivutason assosiaatio luo mitään toista kopiota mistään. Tiedosto upotetaan kerran ja se rekisteröidään EmbeddedFiles-nimipuuhun täsmälleen kuten dokumenttitason liitekin, samaa tiedostomäärittelykoneistoa käyttäen. Ero on siinä, mihin viittaus ja sen suhdeavain kirjoitetaan: sivusanakirjaan dokumenttikatalogin sijaan
Seuraa kaksi seurausta. Ensinnäkin lukija, joka tuntee vain dokumenttitason liitteet, löytää sisällön silti, koska se on juuri siinä nimipuussa, jota tällainen lukija selailee. Toiseksi sivuassosiaation tyhjentäminen poistaa sidonnan, ei tiedostoa. ClearPageAssociatedFiles irrottaa sivun sen assosioduista tiedostoista ja jättää sisällöt tavoitettavissa nimipuun kautta, mikä on konservatiivinen käytös: operaation, joka sanoo tyhjennä assosiaatio, ei pitäisi hiljaa tuhota dataa, johon dokumentin jokin toinen osa voi viitata
Sillä funktiolla on yksi tarkoituksella kapea onnistumisehto, joka kannattaa tuntea. Se raportoi onnistumisen vain silloin, kun sivu todella kantoi /AF-avainta. Sivu, jolla ei koskaan ollut assosiaatioita, palauttaa epäonnistumisen iloisen vahvistuksen sijaan, joten kutsuja ei voi sekoittaa no-opia valmiiksi siivoukseksi
var
Lib: TPDFlib;
Idx, I: Integer;
begin
Lib := TPDFlib.Create(nil);
try
Lib.LoadFromFile('survey-report.pdf');
// Liitä mittaussarja, joka tuotti kaavion sivulla 3
Idx := Lib.AddPageAssociatedFileFromFile(3,
'series-03.csv', // tiedosto levylä
'measurements.csv', // näyttönimi PDF:n sisällä
'text/csv', // MIME-tyyppi
'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;
Suhdemerkkijono ei ole käytännössä vapaata tekstiä. ISO 32000-2 määrittelee sanaston, Source, Data, Alternative, Supplement, EncryptedPayload, FormData, Schema ja Unspecified, ja kuluttajat nojaavat siihen. Data kaavion takana oleville luvuille, Source dokumentille, josta sivu generoitiin, Alternative vastaavalle esitykselle. Valitse sanastosta silloinkin, kun mikään putkesi osa ei vielä lue sitä, koska ketjun seuraava työkalu saattaa
Miksi sama haku tarvitsee FollowRefin molempiin suuntiin?
Koska viittausten seuraaminen vastaa kahteen eri kysymykseen, ja koodin on tunnettava, kumpaa se kysyy. Avainhaku, joka seuraa epäsuoria viittauksia, palauttaa objektin, johon viittaus osoittaa. Haku, joka ei seuraa, palauttaa itse viittauksen. Molemmat ovat oikein, ja väärän käyttäminen tuottaa hiljaisen väärän käytöksen virheen sijaan
Assosioidun tiedoston lukeminen havainnollistaa ensimmäistä suuntaa. Saadaksesi /EF- ja /F-avainten takana olevan tiedostomäärittelyn upotetun virran objektinumeron, haun ei tule seurata, koska seuraaminen ratkaisee viittauksen virtaobjektiksi ja objektinumero on poissa. Sääntö yleistyy: mikä tahansa koodipolku, joka tarvitsee objektin identiteetin objektin sisällön sijaan, on otettava raakaviittaus
Valinnainen sisältö näyttää vastakkaisen suunnan, ja sen löytäminen maksoi enemmän. Valinnaisen sisällön ominaisuussanakirja kirjoitetaan katalogiin epäsuorana objektina, joten ilman seuraamista sen takaisin lukeva koodi saa viittauksen sanakirjan sijaan. Kyseisen arvon tyyppitarkistus epäonnistuu silloin, ja luonnollinen varahaara, jos konfiguraatiota ei ole, luo yksi, ajautuu ja ylikirjoittaa sinne jo tallennetun konfiguraation. Mikään ei nosta poikkeusta. Artikkelin valinnaiset sisältöryhmät ja tasot kuvaamat tasot menettävät yksinkertaisesti oletusnäkyvyystilansa
Oppitunti yleistyy kummankin tapauksen ohi. Kun haku voi palauttaa joko viittauksen tai objektin, paljas tyyppitarkistus ei ole virheenkäsittelyä: se on haara, joka lopulta otetaan väärästä syystä. Päätä eksplisiittisesti, mitä kukin kutsupaikka tarvitsee, ja suosi suoraan kysymykseen vastaavaa julkista API:a, kuten valinnaisen sisällön määräominaisuutta, sen sijaan, että kurkistaisit suojatun accessorin kautta katalogisanakirjaan
// Dokumenttitason liitteet ja sivutason assosiaatiot elävät rinnakkain.
// Upotettu tiedosto voidaan merkitä assosioiduksi myös dokumenttitasolla
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));
// Tyhjentäminen irrottaa sivusidonnaisuuden; sisältö pysyy nimipuussa
if Lib.ClearPageAssociatedFiles(3) > 0 then
Writeln('page 3 associations removed, payloads still reachable');
Mitä yhteensopivuustilat tekevät liitteille
Arkistointiprofiilit rajoittavat sitä, mitä saa upottaa, ja rajoitus valvotaan sisääntulopisteessä eikä tallennushetkellä. PDF/A-1 kieltää upotetut tiedostot kokonaan, PDF/A-2 sallii vain upotetut PDF/A-dokumentit, ja PDF/A-3 on se profiili, joka avasi upottamisen mielivaltaisille tiedostotyypeille, ja juuri siksi hybridilaskuformaatit rakennetaan sen päälle
PDFlibPas kieltäytyy liitteestä, kun aktiivinen yhteensopivuustila ei sitä salli, jo kutsuhetkellä, ei satojen operaatioiden päässä tulostuksen aikana. Tuo on tarkoituksellinen valinta siitä, missä virheeseen reagointi on halvinta: hylkäys kutsupaikalla nimeää tiedoston, jota olit lisäämässä, kun taas hylkäys tallennushetkellä nimeää dokumentin ja jättää sinut selvittämään, kumpi neljästäkymmenestä liitteestä sen aiheutti
Tämä on myös syy, miksi assosioidut tiedostot näkyvät niin usein sähköisessä laskutuksessa. Hybridilasku on PDF, jonka ihminen lukee ja jonka mukana kulkee koneellisesti luettava XML-sisältö oikealla suhteella merkittynä, ja sekä säiliöprofiili että suhdeavain ovat spesifikaation osa, eivät konventioita. Tuo rakennelma on käsitelty artikkelissa Factur-X- ja ZUGFeRD-hybridilaskujen rakentaminen, ja metadatapuoli artikkelissa PDF/A-3:n XMP-laajennusskeema
Milloin assosiaation pitää olla sivukohtainen dokumenttikohtaisen sijaan?
Silloin, kun kuluttajan tarvitsee tietää, mille sivulle data kuuluu, eikä muulloin. Dokumenttitason liitteet ovat yksinkertaisempia, laajemmin katselinten tukemia ja riittäviä aina silloin, kun sisältö kuvaa koko dokumentia: laskun XML, allekirjoitusmanifesti, lähdearkisto. Ota sivutason assosiaatio käyttöön, kun sisältö on aidosti sivukohtaista ja sivun identiteetti on osa sen merkitystä
Tuki on käytännön rajoite. Sivutason Associated Files on PDF 2.0 -konstruktio, ja katselintuki on ohuempi kuin dokumenttitason liitteillä. Koska sisältö on kummassakin tapauksessa nimipuussa, /AF:n sivuilta ohittava katselin näyttää tiedoston silti liiteluettelossaan, eli heikkeneminen on armollista. Mutta jos sivusidonnaisuus on kuluttajallesi olennaista hyödyllisen metadatan sijaan, varmista se lukija, jota todella kohdat, älä oleta
Sivutason Associated Files, dokumenttitason liitteet ja kumpaakin ohjaavat arkistointiprofiilien portit toimituvat PDFlibPas Delphi PDF -kirjaston mukana. Jos korjailet samalla vanhempia tiedostoja matkan varrella, artikkelin PDF/A-muunnos metadatan korjauksella metadata- ja yhteensopivuustyö on se, mikä päättää, mikä näistä liitereiteistä on sinulle alun pitäen edes tarjolla