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 Signature -
Programmatic 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_identifier
dcc.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) do
administrative_data do
core_data do
unique_identifier "urn:uuid:00000000-0000-0000-0000-000000000001"
country_code "DE"
used_lang "en"
mandatory_lang "en"
begin_performance_date Date.today
end_performance_date Date.today
end
items do
item(model: "Pt100", manufacturer: "ACME Sensors") do
name { content lang: "en", value: "Resistance Thermometer" }
end
end
calibration_laboratory do
calibration_laboratory_code "PTB-123"
contact do
name { content lang: "en", value: "Calibration Lab" }
e_mail "lab@example.org"
location do
city "Berlin"
country_code "DE"
end
end
end
resp_persons do
resp_person do
person do
name { content lang: "en", value: "Dr. Jane Doe" }
e_mail "jane@example.org"
end
main_signer true
end
end
customer do
name { content lang: "en", value: "Acme Corp" }
end
end
measurement_results do
measurement_result do
name { content lang: "en", value: "Resistance at 0 °C" }
results do
result do
name { content lang: "en", value: "R(0 °C)" }
data do
quantity do
name { content lang: "en", value: "Measured resistance" }
# D-SI quantity element (si:real) is wired via the typed model
end
end
end
end
end
end
end
puts dcc.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.