A Ruby library for parsing, validating, converting, signing, and building PTB Digital Calibration Certificates (DCC) and D-SI quantity documents.
Built on top of the
lutaml-model framework, dcc
provides a fully typed Ruby object representation of both the DCC and D-SI
XML schemas, with per-major-version class hierarchies mirroring the approach
used by the mml gem for MathML.
A Digital Calibration Certificate (DCC) is an XML-based, machine-readable calibration certificate developed by Germany’s national metrology institute, the Physikalisch-Technische Bundesanstalt (PTB). It is designed to replace traditional paper-based calibration certificates with a format that both humans and machines can process automatically.
A DCC document contains three primary sections:
Administrative data — identifies the calibration laboratory, the customer, the calibrated item(s), responsible persons, performance dates, and any statements about traceability or conformity.
Measurement results — the actual calibration data: measured values, uncertainties, units, environmental conditions, and the methods/equipment used. Each measurement quantity is expressed using the D-SI format.
Document — optional attached files (PDF reports, spreadsheets, images) embedded as base64 binary data.
The certificate can be digitally signed using W3C XMLDSig to guarantee authenticity and integrity.
D-SI (Digital System of Units) is a companion XML format for expressing SI-based measurement quantities with full uncertainty information. A D-SI quantity carries the value, unit (in siunitx notation), and an uncertainty model (standard, expanded with coverage factor k, or coverage interval).
For example, a resistance measurement of 100.0225 Ω ± 0.003 Ω (k=2):
<si:real>
<si:value>100.0225</si:value>
<si:unit>\ohm</si:unit>
<si:expandedMU>
<si:valueExpandedMU>0.003</si:valueExpandedMU>
<si:coverageFactor>2</si:coverageFactor>
<si:coverageProbability>0.95</si:coverageProbability>
</si:expandedMU>
</si:real>D-SI also supports complex quantities, constants, lists (both verbose and compact XML-list forms), hybrid multi-unit representations, covariance matrices, and coverage regions for multivariate uncertainties.
Fully typed object model for DCC v2.x and v3.x (no more XPath over
lxml)Fully typed object model for D-SI v1.x and v2.x
Lossless round-trip XML fidelity (parsing then serializing is byte-equivalent after canonicalization via
moxml)Pure-Ruby Schematron engine implementing the 14 PTB Schematron patterns (no Java/Saxon-HE dependency)
XSD validation against all 12 bundled DCC schema versions
JSON / YAML / CSV / HTML converters
MathML formula support via the
mmlgem (typed model, not raw strings)XMLDSig signature signing and verification via
moxmlnative SignatureProgrammatic DCC builder DSL for issuing new certificates
Structural diff of two certificates
Version migration helpers
Thor-based CLI with
validate,convert,extract,signature,transform,inspect,diff, andissuecommands
Install the gem:
$ gem install dcc
Parse a certificate:
require"dcc"dcc=Dcc.parse(File.read("certificate.xml"))dcc.administrative_data.core_data.unique_identifierdcc.measurement_results.measurement_result.first.results.result.first.data.first.quantity.first.nameValidate:
result=Dcc::Validate::Xsd.call(File.read("certificate.xml"),version: "3.3.0")result.ok?# => trueUse the builder DSL to issue a certificate programmatically:
require"dcc"dcc=Dcc.build(version: 3)doadministrative_datadocore_datadounique_identifier"urn:uuid:00000000-0000-0000-0000-000000000001"country_code"DE"used_lang"en"mandatory_lang"en"begin_performance_dateDate.todayend_performance_dateDate.todayenditemsdoitem(model: "Pt100",manufacturer: "ACME Sensors")doname{contentlang: "en",value: "Resistance Thermometer"}endendcalibration_laboratorydocalibration_laboratory_code"PTB-123"contactdoname{contentlang: "en",value: "Calibration Lab"}e_mail"lab@example.org"locationdocity"Berlin"country_code"DE"endendendresp_personsdoresp_persondopersondoname{contentlang: "en",value: "Dr. Jane Doe"}e_mail"jane@example.org"endmain_signertrueendendcustomerdoname{contentlang: "en",value: "Acme Corp"}endendmeasurement_resultsdomeasurement_resultdoname{contentlang: "en",value: "Resistance at 0 °C"}resultsdoresultdoname{contentlang: "en",value: "R(0 °C)"}datadoquantitydoname{contentlang: "en",value: "Measured resistance"}# D-SI quantity element (si:real) is wired via the typed modelendendendendendendendputsdcc.to_xmlSign with an X.509 certificate and RSA private key:
require"dcc"cert_pem=File.read("cert.pem")key_pem=File.read("cert.key")signed_xml=Dcc::Signature::Signer.call(File.read("certificate.xml"),cert_pem: cert_pem,key_pem: key_pem,)File.write("certificate_signed.xml",signed_xml)Verify a signed certificate:
result=Dcc::Signature::Verifier.call(File.read("certificate_signed.xml"),ca_cert_pem: cert_pem,)result.valid?# => true$ dcc inspect certificate.xml $ dcc validate all certificate.xml $ dcc convert json certificate.xml -o certificate.json $ dcc extract files certificate.xml $ dcc signature sign cert.pem key.pem certificate.xml -o signed.xml $ dcc signature verify cert.pem signed.xml $ dcc diff a.xml b.xml
MIT — see LICENSE.