39 releases (1 stable)
Uses new Rust 2024
| 1.0.0+1.0.0 | Apr 14, 2026 |
|---|---|
| 0.905.4+0.9.5 | Apr 16, 2026 |
| 0.905.3+0.9.5 | Oct 27, 2025 |
| 0.902.4+0.9.2 | Apr 15, 2026 |
| 0.2.2+0.2.1 | Jul 31, 2024 |
#100 in WebAssembly
475KB
4.5K
SLoC
xoev-xwasser
The XÖV data exchange standard XWasser is used for the digital exchange of data between operators of water supply systems (operators), who are responsible for regular drinking water testing in accordance with the quality standards of the German Drinking Water Ordinance (TrinkwV), and the responsible public health authorities (GA) as well as other authorities and diagnostic service providers. The standard therefore also covers the direct transmission of test reports from approved testing institutes (laboratories) to the health authorities as well as the annual transmission of drinking water quality data by the health authorities to the competent supreme state authority (OLB), which is subject to reporting requirements. The XWasser standard is part of the project "Nationwide standardized digital data exchange for drinking water hygiene (SHAPTH)" of all 16 federal states within the framework of the Pact for the Public Health Service (ÖGD).
Legal
Licensed under MIT license.
Versioning
This crate follows the latest minor and patch versions for each maintained major version.
The crate versions follow the X.Y.Z+A.B.C pattern:
- The major version
Xis the upstream XÖV XWasser API compatibility version:300for 3.Y.Z
- The patch
Yversion is incremented when making XÖV XWasser update. It is equal toB*100 + C. - The patch
Zversion is incremented when making internal changes to the crate. A.B.Ccontains the full upstream XÖV XWasser version, like0.2.1or0.5.0. Note that this field is actually ignored in comparisons and only there for documentation.
Features
This crate provides several features that can be enabled:
| Feature | Description |
|---|---|
builder |
Enables builder patterns for type construction using TypedBuilder |
wasm |
Enables WebAssembly bindings using wasm-bindgen and tsify |
schema |
Enables XSD schema validation |
trace |
Enables tracing for debugging |
Default Features
By default, no features are enabled. To use the crate with builders and schema validation:
xoev-xwasser = { version = "1.0.0", features = ["builder", "schema"] }
Builder Pattern
The builder feature enables a fluent API for constructing XML messages:
use xoev_xwasser::{
builder::{
pruefbericht::pruefbericht_type,
transport::{nachrichtenkopf_g2g, NachrichtenTypEnum},
vorgang::identifikation_vorgang,
},
model::{
signature::Signature,
transport::VorgangTransportieren2010,
vorgang::{Vorgang, VorgangType},
},
};
// Create a Pruefbericht
let pruefbericht = pruefbericht_type(
"1.0".into(),
None,
"test-context".into(),
Default::default(),
);
// Build the message with all required fields
let message = VorgangTransportieren2010::builder()
.produkt("MyApp".into())
.produkthersteller("My Company".into())
.produktversion("1.0.0".into())
.nachrichtenkopf_g2g(nachrichtenkopf_g2g(
NachrichtenTypEnum::VorgangTransportieren2010,
))
.vorgang(
Vorgang::builder()
.identifikation_vorgang(identifikation_vorgang(None))
.vorgang_type(VorgangType::Pruefbericht(pruefbericht))
.bemerkung(None)
.anlage(Default::default())
.build(),
)
.zusatzinformationen(Default::default())
.signature(Some(Signature { exists: true }))
.build();
Serialization
The crate supports both XML and JSON serialization:
use raxb::{ser::to_string, de::from_str};
use serde_json;
// Serialize to XML
let xml = to_string(&message)?;
// Serialize to JSON
let json = serde_json::to_string(&message)?;
// Deserialize from XML
let parsed: VorgangTransportieren2010 = from_str(&xml)?;
Schema Validation
The schema feature compiles XSD schemas into a binary format (.xsdb) and provides validation:
use xoev_xwasser::schemas::XmlValidation;
let validation = XmlValidation::new()?;
validation.validate(xml_bytes)?;
How it works:
- During build/test,
raxb_xmlschema_buildcompilesschemas/V1_0_0/xwasser.xsdto.xsdbformat - The compiled schemas are embedded via
rust_embed - At runtime, XML is validated against the compiled schemas using
raxb_validate
Note: Schema compilation runs automatically via the schema feature test:
cargo test --features schema --test generate_schemas
Usage
Basic Example
use xoev_xwasser::{
builder::{
pruefbericht::pruefbericht_type,
transport::{nachrichtenkopf_g2g, NachrichtenTypEnum},
vorgang::identifikation_vorgang,
},
model::{
signature::Signature,
transport::VorgangTransportieren2010,
vorgang::{Vorgang, VorgangType},
},
};
let pruefbericht = pruefbericht_type(
"1.0".into(),
None,
"context".into(),
Default::default(),
);
let message = VorgangTransportieren2010::builder()
.produkt("MyApp".into())
.produkthersteller("My Company".into())
.produktversion("1.0.0".into())
.nachrichtenkopf_g2g(nachrichtenkopf_g2g(
NachrichtenTypEnum::VorgangTransportieren2010,
))
.vorgang(
Vorgang::builder()
.identifikation_vorgang(identifikation_vorgang(None))
.vorgang_type(VorgangType::Pruefbericht(pruefbericht))
.bemerkung(None)
.anlage(Default::default())
.build(),
)
.zusatzinformationen(Default::default())
.signature(Some(Signature { exists: true }))
.build();
Working with Addresses
use xoev_xwasser::builder::shared::anschrift::anschrift_type;
let addr = anschrift_type(
"Teststr.".into(),
"1".into(),
"12345".into(),
"Testort".into(),
);
Codelist Codes
use xoev_xwasser::model::codes::CodeGesamtbewertungType;
let bewertung = CodeGesamtbewertungType::builder()
.code("1010".into())
.name(None)
.build();
TypeScript / WebAssembly
The crate compiles to WebAssembly for use in TypeScript/JavaScript applications:
npm install xoev-xwasser
Creating XML Messages
import {
create_vorgang_transportieren_2010,
parse_vorgang_transportieren_2010,
VorgangTransportieren2010,
PruefberichtType,
schema,
local_schema,
} from "xoev-xwasser";
import quality_report from "./quality_report.json";
// Create XML from JSON object
const xml = create_vorgang_transportieren_2010(
quality_report as unknown as VorgangTransportieren2010
).replace(schema(), local_schema());
Parsing XML
import { parse_vorgang_transportieren_2010 } from "xoev-xwasser";
const source = `<?xml version="1.0"?>
<VorgangTransportieren2010>...</VorgangTransportieren2010>`;
const obj = parse_vorgang_transportieren_2010(source);
if (obj.vorgang.vorgang_type.t === "Pruefbericht") {
const p = obj.vorgang.vorgang_type.c;
console.log(p.id);
}
Utility Functions
import { vorname, familienname } from "xoev-xwasser/utils";
import { natuerliche_person_type } from "xoev-xwasser";
const person = natuerliche_person_type("Sepp", "Meier");
console.log(vorname(person)); // "Sepp"
console.log(familienname(person)); // "Meier"
Schema Validation (Node.js)
import fs from "fs";
import xmlvalidate, { XmlValidatorError } from "@raxb/validate-wasm";
// Load compiled schema
const xsdBundle = fs.readFileSync(
"node_modules/xoev-xwasser/xwasser-v100.xsdb.bin"
).buffer;
const { XmlValidator } = await xmlvalidate();
const validator = new XmlValidator(new Uint8Array(xsdBundle));
validator.init((err: string) => console.error(err));
// Validate XML
validator.validateXml(xmlString, (err: XmlValidatorError) => {
if (err.level === "fatal") {
console.error({ line: err.line, message: err.message });
}
});
Development
Building
# Build with all features
cargo build --features builder,wasm,schema
# Run tests
cargo test --features builder,schema
# Run clippy
cargo clippy --features builder
Full Build (includes WASM)
./build.sh
Testing
Tests are run with specific feature combinations:
# Core tests
cargo test
# Schema validation tests
cargo test --features schema,trace
# Builder tests
cargo test --features builder
# Full test suite
cargo test --no-default-features --features schema,trace,builder
Code Linting
cargo clippy --features builder --fix --allow-dirty
WASM Development
For WASM builds during development:
# Watch mode with auto-rebuild
cargo watch --watch src -s "./build.sh"
For TypeScript testing:
pnpm i
pnpm test
Dependencies
~5–13MB
~219K SLoC