Teknik Makale

Delphi'de Factur-X XMP için PDF/A-3 Genişletme Şemaları

Bir Factur-X faturası oluşturdunuz (built) ve (and) her (every) kapsayıcı (container) kontrolü geçiyor (passes). Katalog (catalog) bir /AF dizisi taşıyor (carries), EmbeddedFiles isim (name) ağacı (tree) doğru (right) dosya (file) belirtimine (specification) çözümleniyor (resolves), gömülü factur-x.xml doğru Alternative /AFRelationship değerine sahip (has) ve yerleşik (built-in) ValidateFacturXInvoice 1 döndürüyor (returns). Ardından (Then) aynı (same) dosyayı (file), vergi (tax) portallarının kullandığı (use) referans (reference) denetleyicisi (checker) olan veraPDF'den geçirirsiniz (run through) ve (and it) tüm (whole) belgenin geçerli (valid) bir PDF/A-3 olmadığına karar verir (rules). Yapı (structure) doğrudur (is right). Sorun (problem) meta verilerdir (metadata) ve (and the) arıza (failure), tüm (entire) e-fatura iş (workflow) akışında gözden (to miss) kaçırılması en kolay olanlardan biridir (is one of the easiest)

Nedenini (reason) tam (in full) olarak (in full) anlamaya (understanding) değerdir (is worth), çünkü (because) görünür (visible) sayfayla (page) veya (or) eklentiyle (attachment) hiçbir (nothing) ilgisi olmayan (has to do with) ve XMP'nin kendini nasıl (how) tanımladığıyla (describes itself) tamamen (everything) ilgili olan (to do with) bir PDF/A kusuru (defect) sınıfını açıklar. Bu, yeşil bir (a green) kapsayıcı (container) kontrolünün arkasına (behind) saklanan tuzaktır (trap)

Dosyayı başarısızlığa uğratan (fail) dört (four) özellik (properties)

Bir Factur-X faturası, aşağı (downstream) akış (downstream) yazılımının gömülü XML'i ayrıştırmadan (parsing) fatura profilini okuyabilmesi (can read) için kendi (its) XMP paketine (packet) dört (four) özel (custom) özellik yazar. Bunlar, Factur-X ad (namespace) alanında fx önekinin (prefix) altında yaşar: fx:DocumentFileName, fx:DocumentType, fx:Version ve fx:ConformanceLevel. Bunlar, (They are) bir okuyucunun (reader) bu PDF'in (PDF) 1.0 sürümünde (at version 1.0) factur-x.xml adlı (named) bir EN 16931 faturası taşıdığını bilmesi (to know) için ihtiyaç duyduğu (needs) meta verilerdir

Bu (those) dört (four) özelliğin hiçbiri (None) PDF/A'nın önceden (predefines) tanımladığı herhangi bir (any) XMP şemasının parçası (part) değildir. Dublin Core, XMP Basic, PDF ve PDF/A tanımlama (identification) şemaları uyumlu (conforming) bir okuyucu (reader) tarafından bilinir (are known to), ancak fx: bilinmez (is not). veraPDF XMP'de gezindiğinde (walks) ve (and) ad alanını (namespace) tanımadığı (does not recognise) bir özelliğe (property) ulaştığında (reaches), ona (it) özelliğin (property) ne (what) anlama geldiğini (means) söyleyecek (would tell) bir bildirim (declaration) arar (looks for). Eğer (If) bu (that) bildirim (declaration) yoksa (is absent), önceden (predefined) tanımlanmış (predefined) bir şemadan alınmayan (drawn) her (every) özelliğin (property) bir PDF/A genişletme (extension) şemasında açıklanmasını (be described) gerektiren (requires) ISO 19005-3 madde (clause) 6.6.2.3.1'e karşı bir arıza bildirir. Bildirilmeyen (undeclared) dört özellik (properties), dosyanın (file) reddedilmesi (to be rejected) için dört yol (ways) ve bunlardan (them) hiçbiri (not one) bir kapsayıcı (container) denetiminde (check) görünmez (is visible to)

PDF/A'nın neden çıplak (bare) bir özel (custom) özelliği (property) reddettiği (refuses)

PDF/A'nın ne için (what) olduğunu (is for) hatırlayana kadar (until) kural kelime (pedantic) oyunu gibi görünür. Format (format), 2026'nın kurallarından (conventions) hiç haberdar olmayan (never told about) yazılımlar (software) tarafından bir dosyanın (file) on yıllar (decades) sonra (from now) açılabilmesi ve (and) anlaşılabilmesi için (so that) mevcuttur (exists). Uyumlu (conforming) bir okuyucunun (reader), başvurulacak (to consult) harici (external) bir kayıt (registry) defteri olmadan, belgeyi (document) yalnızca (alone) belgeden (from the document) anlaması beklenir

Özel (Custom) meta veriler (metadata), dosya kendi (its own) açıklamasını (description) taşımadığı sürece (unless) bu (that) vaadi (promise) bozar (breaks). Çıplak (bare) bir fx:ConformanceLevel özelliği verildiğinde (Given), gelecekteki (future) bir okuyucu (reader) fx önekinin bağlandığı (binds to) ad (namespace) alanı URI'sini, değerin (value) metin (text) mi, tarih (date) mi yoksa tamsayı (integer) mı olduğunu veya (or) özelliğin belgenin kendisini (itself) mi yoksa (or) harici (external) bir kaynağı (resource) mı tanımladığını bilemez. PDF/A genişletme (extension) şeması (schema) mekanizması bu (that) boşluğu kapatır. Dosyanın (file), sabit (fixed) bir XMP yapısında (structure), ad alanını (namespace), öneki (prefix) ve her (each) özellik için bir değer (value) türünü (type) ve bir internal veya external kategorisini (category) bildirmesine (declare) izin verir (lets). Bu bildirim (declaration) mevcut (present) olduğunda (Once), özellik kendini (self-describing) tanımlar (is self-describing) ve madde 6.6.2.3.1 tatmin edilir (is satisfied). Bu olmadan (Without it), doğrulayıcının (validator) özelliği anlaşılmaz (unintelligible) olarak ele almaktan (to treat) ve dosyayı (file) başarısız yapmaktan (fail) başka (no) seçeneği (choice) yoktur. Kategori (category) ayrımı (distinction) burada (here) önemlidir (matters): bunlar (these) gibi fatura (invoice) özellikleri (properties), PDF işlemcisinin (processor) dışından (from outside) gelen verileri açıklar, bu nedenle (so) internal yerine external olarak (as) bildirilirler (are declared)

Genişletme (extension) şeması (schema) bildiriminin (declaration) ne (What) içerdiği (contains)

Bildirim, (declaration is) üç (three) AIIM tanımlı (defined) ad alanını, (namespaces) pdfaExtension, pdfaSchema ve pdfaProperty, kullanan (uses) XMP paketindeki bir rdf:Description'dır. Bir pdfaExtension:schemas çantasının (bag) içinde (Inside), Factur-X şemasını (schema) adlandıran (names), onun (its) pdfaSchema:namespaceURI ve pdfaSchema:prefix'ini veren (gives) ve ardından (then) bir pdfaSchema:property dizisinde (sequence) dört (four) özelliği listeleyen bir (one) şema (schema) girişi (entry) oturur (sits). Her (Each) özellik (property) bir ad (name), Text olan (of) bir pdfaProperty:valueType ve external olan bir pdfaProperty:category taşır. Aşağıdaki açıklayıcı (illustrative) işaretleme (markup), bu bloğun (that block) şeklini (shape) gösterir

<rdf:Description rdf:about=""
    xmlns:pdfaExtension="http://www.aiim.org/pdfa/ns/extension/"
    xmlns:pdfaSchema="http://www.aiim.org/pdfa/ns/schema#"
    xmlns:pdfaProperty="http://www.aiim.org/pdfa/ns/property#">
  <pdfaExtension:schemas>
    <rdf:Bag>
      <rdf:li rdf:parseType="Resource">
        <pdfaSchema:schema>Factur-X PDFA Extension Schema</pdfaSchema:schema>
        <pdfaSchema:namespaceURI>urn:factur-x:pdfa:CrossIndustryDocument:invoice:1p0#</pdfaSchema:namespaceURI>
        <pdfaSchema:prefix>fx</pdfaSchema:prefix>
        <pdfaSchema:property>
          <rdf:Seq>
            <rdf:li rdf:parseType="Resource">
              <pdfaProperty:name>DocumentFileName</pdfaProperty:name>
              <pdfaProperty:valueType>Text</pdfaProperty:valueType>
              <pdfaProperty:category>external</pdfaProperty:category>
              <pdfaProperty:description>name of the embedded XML invoice file</pdfaProperty:description>
            </rdf:li>
            <!-- DocumentType, Version, ConformanceLevel declared the same way -->
          </rdf:Seq>
        </pdfaSchema:property>
      </rdf:li>
    </rdf:Bag>
  </pdfaExtension:schemas>
</rdf:Description>

Ad alanı (namespace) URI'si ve önek (prefix) sabit (fixed) dizeler (strings) değildir. Profili (profile) takip ederler (follow). Bir Factur-X belgesi, fx önekiyle urn:factur-x:pdfa:CrossIndustryDocument:invoice:1p0# kullanırken (uses), zugferd-invoice.xml aracılığıyla (through) seçilen (selected) bir ZUGFeRD 2.0 dosyası, kendi (its own) şema adı altında (under) farklı bir URI'ye çözümlenir (resolves to). Genişletme (extension) şeması (schema), özellik bloğunun gerçekte (actually) kullandığı (uses) ad (namespace) alanı URI'sinin aynısını bildirmek (declare) zorundadır, aksi (or) takdirde doğrulayıcı ikisini (the two) yine de (still) birbirine bağlayamaz (cannot connect). PDFlibPas, her iki (both) değeri de aktardığınız (you pass) dosya adından ve sürümden türetir (derives), böylece bildirim (declaration) ve (and the) özellik (property) bloğu (block) her zaman (always) eşleşir (agree)

Yardımcı (helper) uygulamanın (The) her iki (both) yarıyı da (halves) birlikte nasıl (How) yazdığı (writes)

PDFlibPas'ta bu (that) XML'i elle (by hand) oluşturmazsınız (do not assemble). Belgeyi (document) bir PDF/A-3 moduna (mode) koyar ve (and) bir yöntem (method) çağırırsınız (call). Factur-X, PDF/A-3 gerektirdiğinden (requires), çözülmesi (to settle) gereken ilk (first) şey uygunluk (conformance) bayrağıdır (flag). SetPDFAMode(7) öğesini çağırmak, tanımlama (identification) şemasında (schema) pdfaid:part'ı 3'e ve pdfaid:conformance'ı U'ya ayarlayan (sets) PDF/A-3u düzeyini seçer. XMP paketi (packet), artık herhangi bir fatura (invoice) meta verisi eklenmeden (is added) önce (before) doğru (right) parçayı (part) ve uygunluğu (conformance) taşıyor (carries)

var
  FileID: Integer;
begin
  PDF.SetPDFAMode(7);            // PDF/A-3u: pdfaid:part=3, conformance=U
  PDF.NewDocument;
  // draw the human-readable invoice page here

  FileID := PDF.AddFacturXAssociatedFileFromString(
    InvoiceXML,                  // raw UTF-8 XML bytes
    'EN16931',                   // ConformanceLevel
    'factur-x.xml',              // embedded file name
    'Factur-X invoice XML',      // /Desc text
    'Alternative',               // /AFRelationship
    '1.0',                       // profile version
    '');                         // optional country code
  if FileID = 0 then
    Exit;                        // not PDF/A-3, or XML/profile mismatch

  PDF.SaveToFile('factur-x.pdf');
end;

AddFacturXAssociatedFileFromString öğesine yapılan tek (single) bir çağrı, (call) başarısız olan (failing) dosyanın (file) eksik (missing) olduğu işi yapar (does). XML'i, adlandırdığınız (you named) ilişkiyle (relationship) bir PDF/A-3 ilişkili dosya (file) olarak gömer (embeds) ve seçilen profil (profile) için şema adıyla (name), ad alanı (namespace) URI'siyle ve önekiyle birlikte (along with) dört fx özelliğini kaydeder (records). Belge (document) kaydedildiğinde (is saved), ApplyFacturXMetadata adlı dahili (internal) bir adım, (step) hem (both) özellik (property) bloğunu (block) hem de (and) eşleşen (matching) pdfaExtension:schemas bildirimini XMP paketine (packet) enjekte eder (injects), böylece özel (custom) özellikler önceden (already) açıklanmış (described) olarak ulaşır (arrive). Yöntem, (The method) belge PDF/A-3 modunda (mode) değilse (is not) veya (or if) XML, beyan edilen (declared) profille (profile) eşleşmiyorsa (does not match) 0 döndürür; bu, (which is) hatalı biçimlendirilmiş (malformed) bir faturanın (invoice) ilk (first) etapta (place) dosyaya (file) ulaşmasını (from reaching) durduran (stops) korumanın (guard) aynısıdır (is the same)

Kapsayıcı (container) kontrolünün (check) göremediği (cannot see) kör (blind) nokta (spot)

Bu (This), açıkça adlandırılması gereken (to name plainly) kısımdır (part), çünkü (because) hatanın (bug) gizlenmesinin (hides) nedenidir (reason). ValidateFacturXInvoice kapsayıcıyı (container) kontrol eder (checks). Kataloğun bir /AF girişine (entry) sahip olduğunu, EmbeddedFiles isim (name) ağacının (tree) mevcut olduğunu (is present), fatura (invoice) XML'inin var olduğunu (exists), gömülü dosya (file) adının (name) profille (profile) eşleştiğini, XML'deki kılavuz (guideline) kimliğinin uygunluk (conformance) düzeyiyle (level) uyuştuğunu (agrees) ve /AFRelationship değerinin PDF/A-3'ün izin verdiği (allows) bir (one) değer olduğunu doğrular (confirms). Bunlar gerçek kontrollerdir ve (and they) gerçek hataları yakalarlar (catch). GetFacturXValidationIssues bunları adlarıyla, MissingCatalogAF, NotPDFA3, ConformanceGuidelineMismatch, InvalidAFRelationship ve InvalidFileNameProfile gibi tanımlayıcılarla bildirir

Kontrol etmediği (does not check) şey (What it), XMP genişletme (extension) şemasının mevcut (present) ve (and) doğru (correct) olup olmadığıdır (whether). Kapsayıcısı (container) kusursuz olan (is flawless) ancak (but whose) fx özellikleri bildirilmemiş (undeclared) olan bir dosya (file), her (every) sorun denetimini (check) geçer ve 1 döndürür, çünkü bu (that) listedeki (list) hiçbir şey (nothing) pdfaExtension:schemas bloğunu (block) incelemez (inspects). Elle oluşturulmuş (hand-built) bir faturanın (invoice) veya (or) özellik (property) bloğunu bildirim (declaration) olmadan yazan bir boru hattı (pipeline) tarafından üretilen (produced by) bir faturanın yerleşik (built-in) doğrulayıcıdan (validator) başarıyla geçebilmesinin ve (and) yine de (still) veraPDF'de madde 6.6.2.3.1'de başarısız (fail) olmasının tam (precisely) nedeni (why) budur (That is). Kapsayıcı doğrulayıcı (validator) ile PDF/A meta veri doğrulayıcı farklı (different) soruları (questions) yanıtlar (answer) ve yalnızca tam (full) PDF/A denetleyicisi (checker) ikincisini (the second one) yanıtlar (answers)

Hangi (which) katmanın (layer) kırıldığını (broke) bilmek için sorunları (issues) okumak (Reading)

İki (two) katman bağımsız olarak (independently) başarısız olduğundan (fail), doğru tanı koyma (diagnostic) alışkanlığı, önce (first) kapsayıcı (container) sorunlarını (issues) okumak (read) ve temiz (clean) bir sonucu (result), PDF/A meta verileri hakkında hiçbir (never) zaman değil (never), yalnızca kapsayıcı hakkında bir ifade olarak ele almaktır (treat). Harici bir araca (external tool) uzanmadan (you reach for) önce (before) yerleşik (built-in) doğrulamayı çalıştırın (run), sorun listesini toplayın (collect) ve ona (it) göre (on) hareket edin (act)

var
  Issues: WideString;
begin
  if PDF.ValidateFacturXInvoice = 0 then
  begin
    Issues := PDF.GetFacturXValidationIssues('|');
    // container-level identifiers, for example:
    //   MissingCatalogAF, NotPDFA3, MissingEmbeddedFilesNameTree,
    //   ConformanceGuidelineMismatch, InvalidAFRelationship
    WriteLn('Container issues: ', Issues);
  end
  else
    WriteLn('Container OK; verify XMP extension schema with a PDF/A checker.');
end;

Bu (that) çağrı (call) bir sorun (issue) adı (name) döndürdüğünde, (When) hata (fault) kapsayıcıdadır (in the container) ve (and the) mesaj size hangi (which) kısmın (part) olduğunu (is) söyler (tells you). Temiz döndüğünde ve veraPDF dosyayı (file) yine de reddettiğinde, hata (fault) neredeyse (almost) her zaman (always) XMP genişletme (extension) şemasıdır (schema) ve (and the) düzeltme (fix), özellik (property) bloğunu (block) kendiniz (yourself) oluşturmak yerine (rather than) AddFacturXAssociatedFileFromString işlevinin (let) meta verileri (metadata) yazmasına izin vermektir (is to let). Kendi zihninizde (in your own mind) iki (two) soruyu (questions) ayrı (separate) tutmak (Keeping), kafa karıştırıcı bir reddedilmeyi tek satırlık (one-line) bir teşhise dönüştüren şeydir: kapsayıcı sorunları (problems) sorun (issue) listesi aracılığıyla (through) yüzeye çıkar (surface), şema-bildirim (schema-declaration) sorunları yalnızca bir PDF/A doğrulayıcısı aracılığıyla (through) yüzeye çıkar ve ikisini karıştırmak (confusing the two), hatanın gizlenmesine izin veren şeydir (is what)

Dosyanız yapınızı terk etmeden önce nasıl (how) bir uçuş öncesi (preflight) geçiş (pass) çalıştırılacağı (to run) da (including) dahil (including) olmak üzere, daha geniş PDF/A ve PDF/UA uygunluk (conformance) tablosu (picture), PDF/A ve PDF/UA uçuş öncesi incelemesinde ele alınmıştır (is covered in). Faturanızın aynı zamanda erişilebilir (accessible) olması (to be) gerekiyorsa (If), PDF/A-3a ve etiketli (tagged) PDF'in (PDF) bağlı olduğu (depend on) yapı ağacı (structure tree), etiketli-PDF (tagged-PDF) erişilebilirlik (accessibility) makalesinin konusudur (is the subject of). Burada açıklanan genişletme (extension) şeması (schema) işleyişi, bu (this) blog (blog) boyunca belgelenen (documented) Factur-X, ZUGFeRD ve XRechnung profil (profile) desteğinin (support) yanı (alongside) sıra PDFlibPas Delphi PDF Kütüphanesinin (Library) bir parçası (part) olarak gönderilir (ships as)