Skip to content

XFA フォーム — Python / Rust / Node.js / Go / C#

XFA フォームを検出・解析できる唯一のライブラリです。AcroForm フォールバックに頼らず、XML テンプレートを直接読み取ります:

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 とは

XFA フォームは、標準の AcroForm フィールドの代わりに、PDF 内に埋め込まれた XML ベースのテンプレートを使用します。Adobe によって開発され、以下で一般的に使用されています:

  • 政府機関のフォーム — IRS、出入国管理、州政府機関のドキュメント
  • 金融機関のフォーム — ローン申請書、保険請求書
  • 企業のフォーム — 人事オンボーディング、調達、コンプライアンス

XFA は PDF 2.0(ISO 32000-2:2020)で非推奨になりましたが、数百万の既存 XFA ドキュメントが今も流通しています。

XFA と AcroForm の比較

特徴 AcroForm XFA
形式 PDF オブジェクト XML テンプレート
サポート すべての PDF ライブラリ ごく少数の PDF ライブラリ
動的レイアウト なし あり
PDF 2.0 での状態 サポート 非推奨
一般的な作成元 多くのフォーム作成ツール Adobe LiveCycle, Adobe Designer

PyMuPDF と pypdf が XFA フォームを処理できない理由

一般的な Python PDF ライブラリで XFA フォームを読み取ろうとした場合、エラーも警告もなく空の結果が返されることが多いです。これは PyMuPDF、pypdf、pdfplumber、pdfminer に XFA サポートがないためです。

PyMuPDF (fitz) — 黙って空を返す

PyMuPDF の doc.get_form_fields() やページの .widgets() は AcroForm フィールドのみを読み取ります。XFA のみのフォーム(IRS、出入国管理、州政府機関のドキュメントに多い)を使用する PDF では、PyMuPDF は警告なしに空の結果を返します:

# PyMuPDF — XFA データを黙って見逃す
import fitz
doc = fitz.open("government-form.pdf")
fields = doc[0].widgets()  # XFA のみのフォームでは [] を返す
form_data = doc.get_form_fields()  # XFA のみのフォームでは {} を返す

XFA フォームに AcroForm フォールバックレイヤーが含まれている場合、PyMuPDF はフィールドの一部サブセットを返すことがありますが、実際の XFA データ(動的レイアウト、計算値、ネストされたサブフォーム)は見えません。

pypdf — XFA フォームでも空を返す

pypdf のフォームフィールド読み取りも同じ制限に直面します。AcroForm フィールドにのみアクセスでき、XFA サポートはありません:

# pypdf — XFA コンテンツを読み取れない
from pypdf import PdfReader
reader = PdfReader("government-form.pdf")
fields = reader.get_form_text_fields()  # XFA のみのフォームでは {} を返す

pdfplumber と pdfminer — XFA サポートなし

pdfplumber と pdfminer は XFA フォームからのフィールド読み取りを試みません。XFA の検出や抽出のための API はありません。

PDF Oxide — XFA をネイティブに読み取り

PDF Oxide は XFA XML テンプレートを直接パースし、すべてのフィールド、値、フォーム構造を抽出します:

# PDF Oxide — XFA をネイティブに読み取り
from pdf_oxide import PdfDocument
doc = PdfDocument("government-form.pdf")
xfa = doc.analyze_xfa()
print(f"{len(xfa.fields)} fields found")  # すべての XFA フィールドを抽出

これは政府フォーム、IRS ドキュメント、保険申請書、その他すべての XFA ベースの 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("この PDF は XFA フォームを使用しています")
    print(f"  フィールド数: {len(xfa.fields)}")
    print(f"  テンプレートあり: {xfa.has_template}")
    print(f"  データセットあり: {xfa.has_datasets}")
else:
    print("標準 AcroForm(またはフォームなし)")

WASM

WASM では XFA フォームを検出し、AcroForm フィールドの読み取りにフォールバックできます:

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

const doc = new WasmPdfDocument(bytes);
if (doc.hasXfa()) {
  console.log("この PDF は XFA フォームを使用しています");
  // AcroForm フォールバックフィールドを読み取り
  const fields = doc.getFormFields();
  console.log(`AcroForm フォールバックフィールド: ${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 フォーム: {len(xfa_files)}")
print(f"標準フォーム: {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) の XFA フォームget_form_fields().widgets() は XFA のみの PDF で空を返す。XFA サポートなし、追加予定もなし。
  • pypdf の XFA サポートget_form_text_fields() は XFA コンテンツを読み取れない。AcroForm フォールバックフィールドのみ(存在する場合)。
  • pdfplumber — XFA サポートなし。フォーム抽出は AcroForm フィールドに限定。
  • pdfminer — XFA サポートなし。XFA フォームデータの検出や抽出不可。

PDF Oxide は XFA XML テンプレートを直接読み取る唯一の Python PDF ライブラリであり、PyMuPDF、pypdf、pdfplumber、pdfminer では見えないフォーム構造とデータにアクセスできます。

関連ページ