← ALL FIELD NOTES

How to Route Different Documents to the Right Extraction Method

Build a document extraction routing layer that identifies real file types, selects structure-preserving extractors, measures quality, and applies safe fallbacks.

Document extraction routing is a policy layer

A production ingestion queue rarely contains one clean document type. It contains a mixture of HTML exports, native PDFs, scanned PDFs, CSV files, legacy spreadsheets, XLSX workbooks, DOCX reports, presentations, and files whose extensions say one thing while their bytes say another.

The resulting engineering problem is not simply “pick a parser.” It is document extraction routing: determine what a file actually is, determine what structure the downstream system needs, select an extraction method, and decide what to do when the result is incomplete or unsafe.

A router should produce more than text. It should create a defensible record of why a route was selected and whether the outcome met the pipeline’s quality bar.

A useful mental model is:

bytes + supplied metadata
  -> detection evidence
  -> document family and capabilities
  -> primary extractor
  -> quality evaluation
  -> fallback, review, or accepted output

This approach prevents a common failure mode: accepting a successful parser call as proof of a useful extraction.

1. Detect the real format, not just the filename

Filename extensions are convenient routing hints, but they are not format verification. Python’s mimetypes module, for example, maps filenames to MIME types; it does not establish the contents of the file. Upload metadata has the same limitation: OWASP advises treating client-provided content types as spoofable and validating uploads in layers, including signatures and file content (OWASP File Upload Cheat Sheet).

Build detection from independent signals:

  1. Declared type: the HTTP Content-Type or source-system metadata.
  2. Filename pattern: extension and known naming conventions.
  3. Byte signature: magic bytes and content-oriented type detection.
  4. Container inspection: package contents and internal metadata for ZIP-based formats.
  5. Parse probe: a bounded attempt to confirm that the candidate format is readable.

The shared MIME specification describes a layered approach using explicit type information, filename matching, and content-based magic matching, with a generic binary fallback when the type is still unknown (Shared MIME-info Specification).

That does not mean every signal deserves equal weight. A reasonable policy might trust a verified PDF header more than invoice.pdf as a filename. If the filename suggests .xlsx but the file is not a ZIP package, route it as an inconsistency—not as a spreadsheet.

Handle container formats deliberately

DOCX, XLSX, and PPTX files are Open XML packages: ZIP containers containing typed parts and relationships. Their actual document family is represented inside the package, rather than solely by their filename extension (Microsoft Open XML SDK: Package Structure).

For a ZIP-like upload, inspect only enough of the central directory and package metadata to classify it within your resource limits. This distinguishes an XLSX workbook from a DOCX report and avoids sending every ZIP-looking input into a generic archive handler.

When signals conflict, keep the conflict in the route record. A mismatch is useful operational data and can be a security signal.

2. Route by the structure you need to preserve

Correct format identification is necessary, but not sufficient. The selected extraction method should preserve the semantics that matter for the next stage.

Document familyPrimary routePreserveCommon escalation
HTMLDOM-aware HTML parserheadings, links, tables, metadata, visible textsanitization or targeted content selection
Native PDFPDF text/layout extractorpage boundaries, positioned text, optionally layoutalternate layout strategy or OCR evaluation
Scan or image-only PDFOCR pathrecognized text and page provenancemanual review when recognition quality is poor
XLS/XLSXspreadsheet extractorworkbook, sheet, row, cell, formula/value distinctionstreaming/event-based read for large files
DOCX/PPTXOffice package-aware extractorparagraphs, headings, slides, tables, embedded structureformat-specific post-processing
Unknown binaryquarantine or unsupported resultdetector evidencecontrolled review or allowlisted parser addition

HTML: extract from the parsed document, not from markup-shaped text

HTML has defined parsing behavior that constructs a document tree, even for malformed input (WHATWG HTML parsing specification). Route it to an HTML parser so downstream logic can distinguish a heading from a paragraph, a table from a list, and a link destination from visible anchor text.

Flattening HTML directly into plain text too early loses useful context. Instead, retain both a normalized text representation and selected structural fields, such as document title, headings, tables, and links. The exact fields depend on the product, but the routing decision should preserve the option.

PDFs: make the text-versus-image decision first

PDF is a graphics-oriented format, and text order is not guaranteed to match visual reading order. PDFBox notes that default extraction follows the page content stream, which can differ from the order a person sees; it also calls out that a PDF may contain only images rather than extractable text (Apache PDFBox FAQ).

A robust PDF route begins with a lightweight text extraction attempt, then evaluates page-level evidence:

  • extracted character count per page;
  • percentage of pages with usable text;
  • density of text relative to page area or expected content;
  • malformed-character or encoding-warning counts;
  • whether the document is mostly images;
  • whether layout-sensitive content, such as columns or tables, is expected.

If a page has no meaningful text, it may need OCR. OCRmyPDF is designed to add a searchable text layer to scanned PDFs and can avoid OCR for pages that already have text (OCRmyPDF documentation). This supports a targeted policy: OCR only the pages that need it, rather than treating every PDF as a scan.

For PDFs where reading order matters, expose the extractor choice as policy. A position-sorted route may be better for some layouts, but it is not a universal cure for multi-column reports, sidebars, or complex tables. Preserve page references and extraction warnings so later stages can assess the result.

Spreadsheets: keep cell semantics intact

A workbook is not an ordinary text document. Its sheets, rows, cells, values, types, and formulas are part of its meaning. Apache POI provides separate support for legacy XLS and OOXML XLSX formats, and documents event-based processing for lower-memory, read-only workloads (Apache POI Spreadsheet Documentation).

Route spreadsheet files to a spreadsheet-specific extractor that emits structured records such as:

{
  "sheet": "Revenue",
  "row": 18,
  "cells": {
    "A": {"value": "2026-01"},
    "B": {"value": 42150},
    "C": {"formula": "=B18-B17", "displayValue": 3850}
  }
}

Whether to use formula text, cached display values, or both is an explicit product decision. A generic text parser cannot make that decision safely after the structure has been discarded.

Designing an ingestion path for heterogeneous files? Start with an auditable route record before adding more parsers. Create an account to get started.

3. Evaluate extraction quality before accepting it

Exceptions are clear failures. More difficult are extractions that return successfully but are unusable: a scan yields an empty string, a PDF has shuffled columns, or a workbook becomes a stream of values with no sheet context.

Define quality checks by document family. For example:

if document.kind == "pdf" and text_coverage < 0.20:
    route = "ocr_candidate"
elif document.kind == "pdf" and replacement_characters > threshold:
    route = "alternate_pdf_strategy"
elif document.kind == "spreadsheet" and sheet_count == 0:
    route = "failed"
elif document.kind == "html" and visible_text_length == 0:
    route = "content_selection_or_review"
else:
    route = "accepted"

The thresholds are not universal. A one-page image receipt may legitimately have little text, while a 200-page contract probably should not. Calibrate rules on representative samples and keep the metrics alongside the output.

Apache Tika is useful at the detection and first-parse stage because its AutoDetectParser selects parsers based on detected input type and can emit metadata alongside structured content (Apache Tika Java API). But automatic selection is not the full policy. You still need explicit quality gates and format-aware post-processing.

4. Make fallbacks bounded and observable

Fallbacks should be ordered, finite, and explainable. Avoid an unbounded “try every parser” loop.

A practical fallback ladder is:

  1. Try the primary extractor selected by high-confidence detection.
  2. Evaluate quality and parser warnings.
  3. Apply one format-specific alternative, such as a layout-aware PDF strategy.
  4. Escalate eligible PDF pages to OCR when text evidence is insufficient.
  5. Return unsupported, failed, or needs_review with evidence if the quality bar remains unmet.

Every attempt should append to a route record:

{
  "documentId": "ingest-42",
  "detectedType": "application/pdf",
  "detectionEvidence": ["pdf_signature", "filename_match"],
  "selectedRoute": "pdf_text",
  "attempts": [
    {"route": "pdf_text", "characters": 84, "pageCoverage": 0.05},
    {"route": "ocr", "characters": 2948, "pageCoverage": 1.0}
  ],
  "finalStatus": "accepted"
}

This record helps debugging, evaluation, and compliance review. It also keeps downstream consumers from confusing “no text exists” with “the parser did not find text.”

5. Treat parsing as untrusted-workload processing

Routing governs resources as well as correctness. Parser libraries may encounter excessive memory use, infinite loops, or crashes on hostile or malformed inputs. Apache Tika specifically documents these risks and recommends its process-isolated Pipes approach for untrusted production inputs, with timeouts and memory limits (Apache Tika Java API).

At minimum, apply:

  • allowlisted document families and parser capabilities;
  • upload-size and decompression limits;
  • parser timeouts and memory budgets;
  • isolated worker processes for risky parsing steps;
  • malware scanning or sandboxing where appropriate;
  • retention of original bytes separately from extracted derivatives;
  • structured logs without unnecessarily exposing sensitive extracted content.

Tika also supports configuration of detectors and parsers, which is useful when a deployment should restrict which formats are eligible or attach a controlled OCR stage (Apache Tika Configuration).

A PagePith demonstration: validating a parser source

As a small research workflow example, PagePith fetched the Apache Tika Java API documentation at the cited URL and returned a 10,108-character Markdown result. The returned excerpt confirms that Tika can be embedded in a Java application with control over parsing, detection, and configuration. It also surfaced Tika’s warning that some formats can cause severe parser resource problems and pointed to isolated processing with timeouts and memory limits.

That result is useful as evidence for two routing decisions in this article: use auto-detection as an input to policy, and isolate untrusted parsing work. It does not demonstrate a full end-to-end extraction pipeline, accuracy measurement, or any particular PagePith integration. Those claims would require separate proof.

Build routes that can explain themselves

The best document extraction routing systems do not claim that one parser handles every file perfectly. They identify formats from evidence, preserve structure with dedicated extractors, measure whether the output is useful, and make fallback decisions visible.

Start with a small allowlist—HTML, PDF, spreadsheets, and Office packages—then add routes only when you can define their detection evidence, resource envelope, expected output, and failure path.

Start building a more auditable ingestion workflow.

Sources

  1. Apache Tika Java API: Detectors, Parsers, and AutoDetectParserApache Software Foundation
  2. Apache Tika Configuration and Robustness DocumentationApache Software Foundation
  3. Shared MIME-info Specificationfreedesktop.org
  4. OWASP File Upload Cheat SheetOWASP Foundation
  5. Apache PDFBox FAQApache Software Foundation
  6. OCRmyPDF DocumentationOCRmyPDF Project
  7. Apache POI Spreadsheet DocumentationApache Software Foundation
  8. Microsoft Open XML SDK: Package StructureMicrosoft
Document Extraction Routing: A Practical Guide · PagePith