Skip to content

XFA-формы — Python / Rust / Node.js / Go / C#

Обнаруживайте и анализируйте XFA-формы — единственная библиотека, читающая XML-шаблоны напрямую, а не только AcroForm-заглушку:

from pdf_oxide import PdfDocument

doc = PdfDocument("government-form.pdf")
xfa = doc.analyze_xfa()
if xfa:
    print(f"XFA form with {len(xfa.fields)} fields")
    for field in xfa.fields:
        print(f"  {field.name}: {field.field_type}")

XFA (XML Forms Architecture) — устаревший формат форм, используемый многими государственными агентствами, финансовыми организациями и корпоративными системами. Большинство Python-библиотек для PDF вообще не справляются с XFA-формами. PDF Oxide может обнаруживать, анализировать и извлекать данные из них.

Что такое XFA?

XFA-формы используют XML-шаблоны, встроенные внутрь PDF, вместо стандартных полей AcroForm. Они были созданы Adobe и распространены в:

  • Государственных формах — налоговые формы, иммиграционные документы, документы госучреждений
  • Финансовых формах — заявления на кредит, страховые обращения
  • Корпоративных формах — адаптация сотрудников, закупки, соответствие нормам

XFA был признан устаревшим в PDF 2.0 (ISO 32000-2:2020), но миллионы существующих XFA-документов по-прежнему в обращении.

XFA vs AcroForm

Feature AcroForm XFA
Format PDF objects XML templates
Supported by All PDF libraries Few PDF libraries
Dynamic layouts No Yes
PDF 2.0 status Supported Deprecated
Typical source Most form creators Adobe LiveCycle, Adobe Designer

Почему PyMuPDF и pypdf не могут обрабатывать формы XFA

Если вы пробовали читать XFA-формы популярными Python-библиотеками для PDF, вы наверняка видели пустые результаты без каких-либо ошибок или предупреждений. Это потому что PyMuPDF, pypdf, pdfplumber и pdfminer не поддерживают XFA.

PyMuPDF (fitz) — молча возвращает пустые данные

doc.get_form_fields() и .widgets() в PyMuPDF читают только поля AcroForm. Когда PDF использует формы только на XFA (что типично для налоговых, иммиграционных и государственных документов), PyMuPDF возвращает пустые результаты без предупреждения:

# PyMuPDF — silently misses XFA data
import fitz
doc = fitz.open("government-form.pdf")
fields = doc[0].widgets()  # Returns [] on XFA-only forms
form_data = doc.get_form_fields()  # Returns {} on XFA-only forms

Если XFA-форма включает резервный слой AcroForm, PyMuPDF может вернуть частичный набор полей — но фактические данные XFA (динамические макеты, вычисляемые значения, вложенные подформы) невидимы.

pypdf — тоже возвращает пустые данные для форм XFA

Чтение полей форм в pypdf упирается в то же ограничение. Она имеет доступ только к полям AcroForm и не поддерживает XFA:

# pypdf — cannot read XFA content
from pypdf import PdfReader
reader = PdfReader("government-form.pdf")
fields = reader.get_form_text_fields()  # Returns {} on XFA-only forms

pdfplumber и pdfminer — никакой поддержки XFA

pdfplumber и pdfminer даже не пытаются читать поля форм из XFA. У них нет API для обнаружения или извлечения XFA.

PDF Oxide — читает XFA нативно

PDF Oxide парсит XML-шаблоны XFA напрямую, извлекая все поля, значения и структуру формы:

# PDF Oxide — reads XFA natively
from pdf_oxide import PdfDocument
doc = PdfDocument("government-form.pdf")
xfa = doc.analyze_xfa()
print(f"{len(xfa.fields)} fields found")  # All XFA fields extracted

Это работает на государственных формах, налоговых документах, страховых заявлениях и любых других XFA-based PDF — включая формы без резервного слоя AcroForm.

Установка

pip install pdf_oxide

Обнаружение форм XFA

Проверка, содержит ли PDF контент XFA:

Python

from pdf_oxide import PdfDocument

doc = PdfDocument("form.pdf")
xfa = doc.analyze_xfa()

if xfa:
    print("This PDF uses XFA forms")
    print(f"  Fields: {len(xfa.fields)}")
    print(f"  Has template: {xfa.has_template}")
    print(f"  Has datasets: {xfa.has_datasets}")
else:
    print("Standard AcroForm (or no forms)")

WASM

In WASM, you can detect XFA forms and fall back to reading AcroForm fields:

import { WasmPdfDocument } from "pdf-oxide-wasm";

const doc = new WasmPdfDocument(bytes);
if (doc.hasXfa()) {
  console.log("This PDF uses XFA forms");
  // Read any AcroForm fallback fields
  const fields = doc.getFormFields();
  console.log(`AcroForm fallback fields: ${fields.length}`);
}
doc.free();

Анализ полей XFA

Получение информации о каждом поле XFA-формы:

from pdf_oxide import PdfDocument

doc = PdfDocument("tax-form.pdf")
xfa = doc.analyze_xfa()

if xfa:
    for field in xfa.fields:
        print(f"Name: {field.name}")
        print(f"  Type: {field.field_type}")
        print(f"  Value: {field.value}")
        print()

Чтение данных XFA

Извлечение текущих значений полей из XFA-датасетов:

from pdf_oxide import PdfDocument

doc = PdfDocument("filled-xfa.pdf")
xfa = doc.analyze_xfa()

if xfa and xfa.has_datasets:
    data = {}
    for field in xfa.fields:
        if field.value:
            data[field.name] = field.value
    print(data)

Пакетная обработка форм XFA

Сканирование директории для определения, какие PDF используют XFA:

from pdf_oxide import PdfDocument, PdfError
from pathlib import Path

pdf_dir = Path("government-forms/")
xfa_files = []
acroform_files = []

for pdf_path in pdf_dir.glob("*.pdf"):
    try:
        doc = PdfDocument(str(pdf_path))
        xfa = doc.analyze_xfa()
        if xfa:
            xfa_files.append(pdf_path.name)
        else:
            acroform_files.append(pdf_path.name)
    except PdfError as e:
        print(f"Error: {pdf_path.name}: {e}")

print(f"XFA forms: {len(xfa_files)}")
print(f"Standard forms: {len(acroform_files)}")

Rust API

use pdf_oxide::PdfDocument;
use pdf_oxide::xfa::analyze_xfa_document;

let mut doc = PdfDocument::open("xfa-form.pdf")?;
let analysis = analyze_xfa_document(&mut doc)?;

println!("XFA form detected: {} fields", analysis.fields.len());
for field in &analysis.fields {
    println!("  {} ({:?}): {:?}", field.name, field.field_type, field.value);
}

Почему XFA важен

Большинство Python-библиотек для PDF молча игнорируют контент XFA — extract_text() и API полей форм видят только резервный слой AcroForm (если он существует). Многие формы, использующие только XFA, не имеют резервного AcroForm, что делает их невидимыми для других инструментов:

  • PyMuPDF (pymupdf) и XFAget_form_fields() и .widgets() возвращают пустые результаты на PDF с формами только XFA. PyMuPDF не поддерживает XFA и не планирует добавлять эту поддержку.
  • pypdf и XFAget_form_text_fields() в pypdf не может читать контент XFA. Видны только резервные поля AcroForm, если они вообще существуют.
  • pdfplumber — нет поддержки XFA. Извлечение форм ограничено полями AcroForm.
  • pdfminer — нет поддержки XFA. Не может обнаруживать или извлекать данные XFA-форм.

PDF Oxide — единственная Python-библиотека для PDF, которая читает XML-шаблоны XFA напрямую, давая доступ к структуре и данным форм, которые PyMuPDF, pypdf, pdfplumber и pdfminer не видят.

Связанные страницы