Teknik Makale

Delphi'de FDF, XFDF ve XFA Form Veri Değişimi

losLab PDF Library, form verilerini bir PDF'e üç farklı şekilde aktarır: AcroForm alan değerleri için FDF ve XFDF, aynı iki biçim açıklama yorumları için ve doğrudan forma yazılan tam bir XFA XDP paketi. ExportFormDataToXFDF, ImportFormDataFromXFDF, ImportAnnotationsFromFDF, ExportAnnotationsToXFDF ve SetXFAFromString giriş noktalarıdır ve her birinin bir dosya varyantı ile bir dize varyantı vardır

Bu kadar çok yöntemin olmasının nedeni, PDF form verilerinin tek bir şey olmamasıdır. Doldurulmuş bir AcroForm'un alan değerleri vardır, ayrıca inceleme yorumları da taşıyabilir ve eski bir XFA formu, bunlarla hiçbir ilgisi olmayan tamamen XML tabanlı bir uygulama açıklaması barındırır. losLab PDF Library, bu üç konuyu kasıtlı olarak ayrı API'lerde tutar; çünkü bunları birleştirmek, en az ikisine yanlış bir veri modeli dayatacaktır. Hangi aileye ihtiyacınız olduğuna karar vermek ilk tasarım seçimidir ve bu genellikle karşı taraftaki alıcı sistemin gerçekte neyi tükettiğini bildiğiniz an netleşir

FDF, XFDF ve XFA form verileri arasındaki fark nedir?

FDF ve XFDF aynı bilgiyi iki farklı söz diziminde taşır, XFA ise tamamen ayrı bir dünyadır. FDF, minyatür bir PDF söz dizimi belgesidir (ISO 32000-2 §12.7.8): dizelerin bir PDF içinde tam olarak nasıl kaçış karakterleriyle yazıldığı gibi yazıldığı, << /T (ad) /V (değer) >> sözlüklerinden oluşan bir /Fields dizisidir. XFDF, Acrobat ve çoğu form arka ucunun yerel olarak okuyup yazdığı aynı verilerin XML biçimidir (ISO 19444), bir <fields> ağacıdır. XFA ise ne biridir ne de diğeri: PDF'in /AcroForm/XFA üzerinden başvurduğu bir XML Veri Paketi (XDP) olarak saklanan bir XML Form Mimarisi şablonu ve bunun verisidir. Alan değerleri üzerinde birlikte çalışırken FDF veya XFDF'i seçin ve XFA'e yalnızca belgenin ilk olarak bir XFA formu olarak tasarlandığı durumlarda başvurun

FDF ve XFDF dahilinde, losLab PDF Library ikinci bir çizgi çizer: alan değerlerine karşı açıklama yorumları. Form verileri ailesi (ExportFormDataToFDF, ImportFormDataFromFDF, ExportFormDataToXFDF, ImportFormDataFromXFDF) /Fields alt ağacını okur ve yazar, başka hiçbir şeye dokunmaz. Açıklama ailesi (ExportAnnotationsToFDF, ImportAnnotationsFromFDF, ExportAnnotationsToXFDF, ImportAnnotationsFromXFDF) ise Acrobat'ın Yorumları Dışa Aktar ifadesiyle kastettiği /Annots alt ağacını okur ve yazar. İkisi asla çakışmaz, bu nedenle alan değerlerini dışa aktarmak rastgele inceleme notlarını kapsamaz ve yorumları içe aktarmak kullanıcının zaten yazmış olduğu değerleri bozmaz. Bir bileşenin tıklandığında veya yeniden hesaplandığında ne yaptığı ise, etkileşimli form eylemleri ve JavaScript hakkındaki yardımcı notta ele alınan üçüncü bir konudur

Delphi'de FDF veya XFDF'ten bir PDF formu nasıl doldurulur?

Belgeyi yükleyin, bir içe aktarma yöntemini çağırın ve kaydedin. ImportFormDataFromXFDF ve ImportFormDataFromFDF yöntemlerinin her biri gelen form verilerini ayrıştırır, her girdiyi tam nitelikli adıyla bir AcroForm alanıyla eşleştirir, değeri ayarlar ve fiilen güncellenen alan sayısını döndürür. Her iki yöntem de yalnızca hedef PDF'te zaten mevcut olan alanları günceller; hiçbiri formun tanımlamadığı bir ad için alan oluşturmaz, bu da harici veya zararlı bir veri dosyasının formunuzu sessizce büyütmesini engeller

var
  Lib: TPDFlib;
  FieldsSet: Integer;
begin
  Lib := TPDFlib.Create;
  try
    Lib.LoadFromFile('application-blank.pdf', '');
    // XFDF produced by a case-management system, already UTF-8 on disk
    FieldsSet := Lib.ImportFormDataFromXFDF('applicant-1042.xfdf');
    if FieldsSet > 0 then
      Lib.SaveToFile('application-filled.pdf');
  finally
    Lib.Free;
  end;
end;

İki ayrıntı, basit olmayan verilerin bu yolculukta hayatta kalıp kalmayacağını belirler. Birincisi kaçış karakterleridir: FDF, değerleri PDF dize sabitleri olarak saklar, bu nedenle parantez, ters eğik çizgi veya yazdırılamayan bir bayt içeren bir değer ISO 32000-2 §7.3.4.2 içinde tanımlanan sekizlik kaçışla sarılmış olarak gelir; losLab PDF Library içe aktarma sırasında bu kaçışı tersine çevirir, böylece parantezler ve eğik çizgiler kullanıcının yazdığı tam karakterler olarak geri döner. İkinci ise kodlamadır: dosya tabanlı yöntemler XFDF ve FDF'i, XFDF bildiriminin vadettiği ve ASCII olmayan herhangi bir alan değerinin (aksanlı bir ad, bir para birimi simgesi, bir CJK adresi) bozulmadan aktarılması için ihtiyaç duyduğu UTF-8 olarak okur ve yazar. XFDF'i kendiniz oluşturuyorsanız, UTF-8 bildirin ve UTF-8 yazın; böylece içe aktarma işlemi sorunsuz çalışır

Hiyerarşik alanlar, çoklu seçimler ve zengin metin

Hiyerarşik alan adları, basit bir dışa aktarıcının bozulacağı ilk yerdir. AcroForm, iç içe geçmiş bir alana Applicant.FullName gibi noktalı tam bir başlıkla başvurur, ancak XFDF bu noktalı dizeyi tek bir ad özniteliğine koymaz; ISO 19444 bunu <field name="Applicant"><field name="FullName"> olarak iç içe yerleştirir. losLab PDF Library, dışa aktarırken noktalı başlığı iç içe geçmiş <field> öğelerine böler ve içe aktarırken bu öğeleri yeniden tam başlıkta birleştirir, böylece her iki yön de simetrik kalır. Dışa aktarırken uç nokta olmayan üst alanları da atlar, çünkü bir AcroForm'daki bir üst düğüm yalnızca adlandırma seviyesini taşır ve kendine ait bir değeri yoktur; bunu yaymak, gerçek formla eşleşmeyen boş bir <value></value> üretecektir. Çoklu seçimli liste kutuları ikinci tuzaktır: bir seçim alanı aynı anda seçilen birkaç değeri tutabilir, bunu XFDF yinelenen <value> öğeleriyle ve FDF ise bir /V dizisiyle ifade eder; losLab PDF Library bir alanı yalnızca gerçekten çoklu seçimli bir tercih olduğunda birden çok değere böler, böylece sıradan bir çok satırlı metin alanı geçersiz değerlere bölünmek yerine satır sonlarını korur

Zengin metin üçüncüsüdür ve insanların en sık hata yaptığı yerdir. Biçimlendirmeye sahip bir alan, biçimlendirmesini RV girdisinde bir XHTML alt ağacı olarak saklar ve XFDF bunu <value-richtext> içinde taşır. losLab PDF Library bu alt ağacı kaçış karakteri kullanmak yerine canlı bir XML parçası olarak yazar, böylece sonraki bir araç görünür etiketler yerine gerçek zengin metni okur; içe aktarırken ham RV alt ağacını korur ve düz <value> değerini yine de V alanına uygular. Bir alanın her ikisini de sunduğu durumlarda, düz değer V için önceliklidir ve zengin metin RV içinde birlikte taşınır; bu, zengin metin içe aktarımının başka bir aracın zaten ayarlamış olduğu bir değeri sessizce değiştirmesini engelleyen birlikte çalışabilirlik kuralıdır. Zengin metniniz yardımcı teknolojiye belge yapısını iletmek için varsa, bunu etiketli PDF ve erişilebilirlik yapısı hakkındaki notta ele alınan okuma sırasıyla aynı şekilde değerlendirin

var
  Lib: TPDFlib;
const
  XFDF =
    '<?xml version="1.0" encoding="UTF-8"?>' +
    '<xfdf xmlns="http://ns.adobe.com/xfdf/" xml:space="preserve">' +
    '<fields>' +
    '  <field name="Applicant">' +
    '    <field name="FullName"><value>Alice Example</value></field>' +
    '  </field>' +
    '  <field name="Skills">' +
    '    <value>Delphi</value><value>PDF</value>' +
    '  </field>' +
    '  <field name="Notes">' +
    '    <value>See attachment</value>' +
    '    <value-richtext><body><p>See <b>attachment</b></p></body></value-richtext>' +
    '  </field>' +
    '</fields></xfdf>';
begin
  Lib := TPDFlib.Create;
  try
    Lib.LoadFromFile('intake.pdf', '');
    // Applicant.FullName reassembles; Skills fills the /V + /I arrays;
    // Notes gets V from <value> and RV from <value-richtext>
    Lib.ImportFormDataFromXFDFString(XFDF);
    Lib.SaveToFile('intake-filled.pdf');
  finally
    Lib.Free;
  end;
end;

Açıklama yorumları FDF veya XFDF olarak nasıl karşılıklı aktarılır?

Yorumlar açıklama ailesi üzerinden taşınır ve desteklenen alt küme kasıtlı olarak küçüktür. ExportAnnotationsToXFDF ve ImportAnnotationsFromXFDF, FDF eşdeğerleriyle birlikte, temiz bir şekilde karşılıklı aktarılabilen alanlarla birlikte metin stili işaretlemeyi taşır: açıklama alt türü, dikdörtgeni, 0 tabanlı sayfa dizini, T içindeki yazar, Subj içindeki konu, düz Contents ve PDF'in /C DeviceRGB üçlüsünü bir XFDF #RRGGBB özniteliğine eşleyen renk. İçe aktarma yalnızca bilinen öğe adlarını kabul eder ve sayfası aralık dışı olan veya dikdörtgeni eksik olan girdileri atlar; böylece elle düzenlenmiş veya yabancı bir XFDF, belgeye bozuk bir açıklama ekleyemez. Alt kümenin henüz taşımadığı şeyleri açıkça belirtmekte fayda var: zengin metin içerikleri (RC), açılır pencereler, quadpoint'ler, mürekkep listeleri, köşeler ve hazır görünüm akışları şimdilik kapsam dışıdır, bu nedenle vurgulama geometrisi ve özel damga görünümleri bu yoldan sağ çıkamaz. Gerçekte neyin ulaştığını onaylamak için sayfa açıklamalarını veya metin arama ve sayfa öğesi listeleme makalesinde ele alınan geniş öğe ağacını tarayın

var
  Src, Dest: TPDFlib;
  Xfdf: WideString;
begin
  Src := TPDFlib.Create;
  Dest := TPDFlib.Create;
  try
    Src.LoadFromFile('reviewed.pdf', '');
    Xfdf := Src.ExportAnnotationsToXFDFString;   // <annots> subset only

    Dest.LoadFromFile('clean-copy.pdf', '');     // pages must line up by index
    Dest.ImportAnnotationsFromXFDFString(Xfdf);
    Dest.SaveToFile('clean-copy-commented.pdf');
  finally
    Dest.Free;
    Src.Free;
  end;
end;

SetXFAFromString ile tam bir XFA XDP paketi yazma

XFA istisnadır ve SetXFAFromString her şeyi tek seferde nasıl yazacağınızdır. Bu yöntem, şablonu ve veri kümesi paketlerini içeren eksiksiz bir XML Veri Paketini, yani <xdp:xdp> belgesini alır ve bunu /AcroForm/XFA üzerinden başvurulan akış olarak saklar. losLab PDF Library, belgenin hiç AcroForm kapsayıcısı olmadığında bunu talep üzerine oluşturur; böylece XFA'in asılabileceği bir yer sağlamak için geçici bir alan eklemek zorunda kalmazsınız. Ayrıca tuttuğu tüm ayrıştırılmış XFA durumunu atar, böylece daha sonraki bir okuma eski bir önbellek yerine az önce yazdığınız paketi yansıtır. Bir XFA paketi XML olduğundan ve mutlaka UTF-8 olması gerekmediğinden, kitaplık bir UTF-16 bayt sırası işaretini (BOM) algılar ve ayrıştırmadan önce paketi doğru şekilde çözer, bu da varsayılan olarak UTF-16 üreten araçlar tarafından oluşturulan paketler için önem taşır

Paket yerine yerleştirildikten sonra, GetXFAFormFieldValue and SetXFAFormFieldValue bireysel alanlara Scripting Object Model (SOM) yolları üzerinden başvurur. losLab PDF Library standart SOM köklerini ve göreceli yolları kabul eder; bu sayede form1.FullName, $data.form1.FullName ve xfa.datasets.data.form1.FullName yollarının tümü aynı veri düğümüne çözümlenir ve şablon tarafı da $template ve xfa.template yollarını aynı şekilde kabul eder. Bu esneklik, SOM yolları her zaman tam nitelikli formu yayan başka bir sistem tarafından oluşturulduğunda önem kazanır

var
  Lib: TPDFlib;
const
  Xdp =
    '<?xml version="1.0" encoding="UTF-8"?>' +
    '<xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/">' +
    '  <template xmlns="http://www.xfa.org/schema/xfa-template/3.3/">' +
    '    <subform name="form1">' +
    '      <field name="FullName"><ui><textEdit/></ui></field>' +
    '    </subform>' +
    '  </template>' +
    '  <xfa:datasets xmlns:xfa="http://www.xfa.org/schema/xfa-data/1.0/">' +
    '    <xfa:data><form1><FullName>Alice Example</FullName></form1></xfa:data>' +
    '  </xfa:datasets>' +
    '</xdp:xdp>';
begin
  Lib := TPDFlib.Create;
  try
    Lib.SetXFAFromString(Xdp, 0);      // creates the AcroForm container if none exists
    // read back through the data DOM with an SOM path
    if Lib.GetXFAFormFieldValue('form1.FullName') = 'Alice Example' then
      Lib.SetXFAFormFieldValue('form1.FullName', 'Bob Example');
    Lib.SaveToFile('xfa-packet.pdf');
  finally
    Lib.Free;
  end;
end;

Dürüst özet; hiyerarşi, çoklu seçim ve zengin metin dahil olmak üzere alan değerlerinin FDF ve XFDF aracılığıyla tamamen karşılıklı aktarılabildiğidir; açıklama yorumları net boşluklara sahip tanımlanmış bir metin işaretleme alt kümesi olarak karşılıklı aktarılır; XFA ise üstünde alan başına SOM erişimi ile birlikte bir bütün paket olarak yazılır ve okunur. Biçimi tüketiciyle eşleştirin, elle oluşturduğunuz her şey için UTF-8 bildirin ve içe aktarma yöntemlerinin yalnızca belgelere zaten uyan alanlara ve açıklamalara dokunduğunu unutmayın. Burada açıklanan form verileri, açıklama ve XFA yöntemleri, her dışa ve içe aktarma giriş noktası için tam parametre listesini içeren Delphi ve C++Builder için losLab PDF Library'nin bir parçasıdır