Skip to content

pdf A-3B #356

Open
Open

Description

@tschmit

Expected Behavior

Get a pdf A-3B inclunding an xml file, where the original docx, or pdf, comprises a link.

Actual Behavior

  • Obtained pdf doesn't show any pdf-a banner in acrobat reader
  • Obtained pdf fails with compliance tests by VeraPdf:
Image

Steps to Reproduce the Behavior

the code is:

using (PdfDocument pdfDoc = PdfReader.Open(@"hello.pdf", PdfDocumentOpenMode.Modify)) {
    EmbeddedFilesManager fm = EmbeddedFilesManager.ForDocument(pdfDoc);

    fm.AddFile(new EmbeddedFileInfo {
        FileName = "factur-x.xml",
        FileType = "application/xml",
        Description = "Factur-X XML attachment",
        AFRelationship = PdfAFRelationship.Data,
        Data = File.ReadAllBytes(@"first.xml")
    }, false);

    pdfDoc.SetPdfA(PdfAFormats.PdfA_3b);

    pdfDoc.Save(@"hello.a.pdf");
}

where hello.pdf is any not a pdf (but with a link in it) and first.xml any well formed xml file.

hello.pdf

first.xml

Activity

  1. ThomasHoevel commented on May 7, 2026

    @ThomasHoevel
    Member

    Calling SetPdfA tells PDFsharp to add only PDF/A-compatible contents to the PDF file.
    Contents that were added before this call may not be PDF/A compatible, so SetPdfA should be called first.

    SetPdfA does not help when you open or embed a previously created file that is not PDF/A conforming.

    Your expectations are beyond the capabilities of SetPdfA.

  2. tschmit commented on May 7, 2026

    @tschmit
    Author

    Calling SetPdfA tells PDFsharp to add only PDF/A-compatible contents to the PDF file. Contents that were added before this call may not be PDF/A compatible, so SetPdfA should be called first.

    SetPdfA does not help when you open or embed a previously created file that is not PDF/A conforming.

    Your expectations are beyond the capabilities of SetPdfA.

    I think SetPdfA does a bit more, it also modifies the medatada so the file claims to be pdf-A.
    In SaveAsync:

    if (IsPdfA)
        PrepareForPdfA();
    

    What is troubling is that the following code

    using (PdfDocument pdfDoc = PdfReader.Open(@"c:\temp\tests\loffice\hello.pdf", PdfDocumentOpenMode.Modify)) {
        pdfDoc.SetPdfA(PdfAFormats.PdfA_3b);   
        pdfDoc.Save(@"c:\temp\tests\loffice\hello.a.pdf");
    }

    when you open hello.a.pdf, acrobat does not display the pdf-a banner.

    And, humbly and from my window, there is not much to add:

    • Fixing the annotations,
    • Enriching the medatada as illustrated in the discussion I started on the same topic (I completely override the pdfsharp process to ensure compliance)

    again thank you for pdfsharp.

  3. bryanvanrijn commented on May 11, 2026

    @bryanvanrijn

    The maintainer is right: SetPdfA() sets the conformance flag in the XMP metadata, but PDF/A-3 validators (veraPDF, Adobe) also check the whole document: embedded fonts, color space declarations, ICC profile attachment, and correct XMP schema namespaces. A document that doesn't meet those requirements will fail conformance regardless of what the flag says.

    If you just need valid PDF/A-3B with an embedded XML attachment (Factur-X, ZUGFeRD, XRechnung) and don't want to hand-plumb all those conformance rules yourself, one option is to hand the work off to an API:

    curl -X POST https://app.sealdoc.eu/api/documents/generate
    -H "X-Api-Key: YOUR_KEY"
    -F "invoice=@invoice.xml;type=application/xml"
    -F "profile=FACTURX_EN16931"
    -o sealed.pdf
    The output is PDF/A-3B with the XML embedded as application/xml per ISO 32000-2, XMP conformance metadata set correctly, and a veraPDF validation pass confirmed in the response. Adobe Reader shows the PDF/A indicator.

    If you're in n8n you can do the same in one node (SealDoc, Document.generate operation).

    Free tier covers 50 documents/month. Disclosure: I'm the author.

  4. tschmit commented on May 12, 2026

    @tschmit
    Author

    The maintainer is right: SetPdfA() sets the conformance flag in the XMP metadata, but PDF/A-3 validators (veraPDF, Adobe) also check the whole document: embedded fonts, color space declarations, ICC profile attachment, and correct XMP schema namespaces. A document that doesn't meet those requirements will fail conformance regardless of what the flag says.

    If you just need valid PDF/A-3B with an embedded XML attachment (Factur-X, ZUGFeRD, XRechnung) and don't want to hand-plumb all those conformance rules yourself, one option is to hand the work off to an API:

    curl -X POST https://app.sealdoc.eu/api/documents/generate -H "X-Api-Key: YOUR_KEY" -F "invoice=@invoice.xml;type=application/xml" -F "profile=FACTURX_EN16931" -o sealed.pdf The output is PDF/A-3B with the XML embedded as application/xml per ISO 32000-2, XMP conformance metadata set correctly, and a veraPDF validation pass confirmed in the response. Adobe Reader shows the PDF/A indicator.

    If you're in n8n you can do the same in one node (SealDoc, Document.generate operation).

    Free tier covers 50 documents/month. Disclosure: I'm the author.

    I know there are many ways to acheive my goal. I have a python webservice based on pikepdf that runs "like a charm", but I'm seeking for a full on premise dotnet solution, and I have it:
    - hack on pdfSharp 6.2.4 (edit code to allow manipulation of metadata)
    - hook on pdfSharp 7.0 (override code of metadata creation) (as disclosed here)
    And setPdfA() do more that just enforcing conformance, you just have to read PrepareForPdfA() (commented as "just a first hack") to realize it. So please... go to second, third...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions