Rust crate containing structs and validators to create Crossref conform XML output – with confidence.
  • Rust 99.1%
  • Shell 0.9%
Find a file
2026-01-28 10:53:12 +01:00
schemas automatically patch schemas for validation 2025-12-23 23:20:50 +01:00
src fix(lint): ensure dead function is allowed 2026-01-28 10:53:12 +01:00
.gitignore chore: ignore tests/xml_output 2026-01-28 10:41:21 +01:00
Cargo.toml chore: update readme, prep for crate submission 2026-01-28 10:50:09 +01:00
collect-schemas.sh automatically patch schemas for validation 2025-12-23 23:20:50 +01:00
LICENSE Initial commit 2025-12-21 15:40:13 +00:00
README.md chore: update readme, prep for crate submission 2026-01-28 10:50:09 +01:00
schema.patch automatically patch schemas for validation 2025-12-23 23:20:50 +01:00

crossref-xml

Rust crate containing structs and validators to create Crossref conform XML output with confidence. Based on the 5.4.0 Crossref schema (documentation).

This is a hand-curated set of structs, as generating it from the XSD schema directly is a great idea, but has failed in quirky ways. This crate ensures generated XML is valid. It is not supposed to be feature complete from the get-go, but to provide a stable development base to keep evolving schema support.

This crate is used in ResearchEquals until there is more complete documentation I recommend viewing the tests in the library to help orient yourself. Note: Requires intricate knowledge of the Crossref schema.

Philosophy

Crossref has a complex schema with many requirements. The philosophy of this crate is for you to focus on your content as much as possible and not be exposed to more complexities than that.

Concretely this means:

  • One submission per publication
  • Logical defaults for our use case (may not be logical for yours)
    • Digital first
    • Registrant and depositor are the same
    • English language default
    • Archived in the Internet Archive
  • Organizations, people, anonymous this is the order in which authors can appear. Within they can be arranged as desired.

Getting started

cargo add crossref-xml

Then use it wherever you need to by importing it and creating your XML:

use crossref_xml::DoiBatch;
use crossref_xml::journal::Journal;
use crossref_xml::journal::article::JournalArticle;

let mut batch = DoiBatch::new("Test Publisher".to_string(), "test@example.com".to_string());

let mut journal = Journal::minimal(
    "Test Journal".to_string(),
    "10.53962/test.journal".to_string(),
    "https://example.com/journal".to_string(),
);

let mut article = JournalArticle::minimal(
    "Example Research Article".to_string(),
    2024,
    "10.53962/test.article.001".to_string(),
    "https://example.com/article/001".to_string(),
);

journal.add_article(article);
batch.add_journal(journal);


let xml = batch.to_xml().expect("Should serialize to XML");
println!(xml)

Implementation progress

There are many structs needed to be feature complete the current implementation is only partly there:

flowchart LR
    A[✅✅doi_batch] --> B[✅✅body]
    A --> C[✅✅head]
    B --> D[✅✅journal]
    B --> E[book]
    B --> F[conference]
    B --> G[sa_component]
    B --> H[dissertation]
    B --> I[report-paper]
    B --> J[standard]
    B --> K[database]
    B --> L[peer_review]
    B --> M[pending_publication]
    B --> N[posted_content]
    D --> O[✅✅journal_metadata]
    D --> P[✅✅journal_issue]
    D --> Q[✅✅journal_article]

Please note that there may be opinionated omissions up to this point within the implemented parts, so if you have specific requests, please visit the repository and open up the discussion (or email support@researchequals.com).