Skip to content
EN DE
Back to Knowledge
LearningsPublished

OCR to XML: parsing is only the first check

  • Python
  • XML
  • data-quality
  • research

Three different kinds of correctness

My research work at the University of Münster included processing and validating more than 1,700 pages of OCR output into conformant XML. The interesting part was not only generating XML, but knowing what each validation step actually proved. A useful way to reason about this kind of work is to separate three checks:

  1. Well-formedness: can an XML parser read the document?
  2. Conformance: does the document satisfy the required schema and project rules?
  3. Fidelity: does the text still represent the source material accurately?

Passing the first check does not imply passing the other two.

Let a serializer handle XML escaping

Building XML with string concatenation makes characters such as & and < easy to mishandle. A serializer handles their representation in XML text nodes.

This standalone illustration uses Python’s standard library; it is not code from the university project:

from xml.etree.ElementTree import Element, SubElement, tostring

document = Element("document")
page = SubElement(document, "page", {"number": "1"})
page.text = "Research & archives <catalogue>"

xml_bytes = tostring(
    document,
    encoding="utf-8",
    xml_declaration=True,
)
print(xml_bytes.decode("utf-8"))

ElementTree provides parsing and serialization. It is not an XSD validation engine. If a project requires schema validation, use a validator appropriate to that schema as an additional step.

Preserve provenance

Keep a stable connection between an output document and its source page. Record transformations that materially change the text, and make ambiguous OCR corrections reviewable rather than silently guessing.

For example, a syntactically valid date can still be the wrong date because OCR confused a character. Structural validation helps define the allowed form; comparison with source material answers a different question.

Separate data checks from publication

For research publishing, Quarto distinguishes rendering from executing computations. Its freeze option can reuse prior computation results, so a successful site build should not be interpreted as proof that source data was reprocessed or revalidated.

Make it explicit which stage validates data, which stage renders it, and which artifacts are reused. That separation gives a reviewer a clearer account of what a successful build actually proves. In research tooling, the safest workflow is one where structural checks and source fidelity are visible as separate responsibilities.

Sources

Technical references reviewed on 13 September 2026.