How stainless steel inspection data travels from an AAS 3.0 document to PMDCO-conformant RDF.
The Manufacturing-X dataspace exposes steel inspection data as AAS (Asset Administration Shell) 3.0
documents following the EN 10204 standard for metallic materials test reports.
AAS 3.0 uses a hierarchical submodel tree with idShort identifiers and semantic IDs
referencing IDTA (Industrial Digital Twin Association) submodel templates.
Unlike the Catena-X SAMM JSON, AAS encodes property semantics via external semantic IDs
(e.g., https://admin-shell.io/idta/InspectionDocumentsOfSteelProducts/TensileStrengthMean/1/0)
rather than field names. The structure is fundamentally incompatible with SAMM without
a dedicated transformation.
{
"assetAdministrationShells": [{ "idShort": "InspectionDocumentsOfSteelProductsAAS" }],
"submodels": [{
"idShort": "InspectionDocumentsOfSteelProducts",
"submodelElements": [
/* MechanicalTests — TensileTest__00__ sub-collection */
{
"idShort": "TensileStrengthMean",
"semanticId": { "keys": [{
"value": "https://admin-shell.io/idta/...TensileStrengthMean/1/0"
}]},
"value": "632", "modelType": "Property"
},
{ "idShort": "YieldOrProofStrengthMean", "value": "276", "modelType": "Property" },
{ "idShort": "ElongationAfterFractureMean", "value": "60", "modelType": "Property" },
/* ChemicalAnalysis sub-collection — 9 mass fractions with values */
{ "idShort": "MassFraction_C", "value": "0.022", "modelType": "Property" },
{ "idShort": "MassFraction_Cr", "value": "16.9", "modelType": "Property" },
{ "idShort": "MassFraction_Mn", "value": "1.51", "modelType": "Property" },
{ "idShort": "MassFraction_Mo", "value": "2.01", "modelType": "Property" },
{ "idShort": "MassFraction_N", "value": "0.024", "modelType": "Property" },
{ "idShort": "MassFraction_Ni", "value": "10", "modelType": "Property" },
{ "idShort": "MassFraction_P", "value": "0.036", "modelType": "Property" },
{ "idShort": "MassFraction_S", "value": "0.002", "modelType": "Property" },
{ "idShort": "MassFraction_Si", "value": "0.4", "modelType": "Property" }
]
}]
}
idShort references, and IDTA semantic IRIs — none of which align with the Catena-X SAMM keys or standard QUDT units.
The AAS 3.0 JSON is first converted to RDF using py-aas-rdf, which produces AAS-conformant RDF triples stored in a pyoxigraph in-memory store. The resulting RDF faithfully represents the AAS structure (submodel elements, semantic IDs, display names) as linked data.
At this stage the RDF is "AAS/RDF" — the hierarchical AAS structure is preserved but not yet aligned with PMDCO. A subsequent SPARQL INSERT (the AAS2KG mapping) performs the PMDCO alignment in the next step.
The AAS2KG tool chain is developed by MI-Fraunhofer IWM. The steel inspection document pipeline is documented at: dataportal.material-digital.de/dataset/steel-inspection-document-mapro ↗
The AAS2KG mapping is a SPARQL INSERT that reads AAS/RDF from the staging graph and writes PMDCO-conformant output. Each IDTA semantic ID is resolved to a TTO (Taxonomy Thermodynamic Ontology) or PMDCO quality class, and numeric values are linked via OBI datum + QUDT QuantityValue patterns.
PREFIX aas: <https://admin-shell.io/aas/3/0/> PREFIX tto: <https://w3id.org/pmd/tto/> PREFIX pmd: <https://w3id.org/pmd/co/> PREFIX obo: <http://purl.obolibrary.org/obo/> PREFIX qudt: <https://qudt.org/schema/qudt/> PREFIX unit: <https://qudt.org/vocab/unit/> INSERT { GRAPH <urn:graph:mfgx> { # Component is a PMDCO Object ex:PLACEHOLDER_material a pmd:PMD_0000000, obo:BFO_0000040 ; rdfs:label ?materialNameValueFinal . # Tensile strength: TTO class + OBI datum chain ex:PLACEHOLDER_tensile_strength a tto:TTO_0000053 ; obo:RO_0000052 ex:PLACEHOLDER_material ; obo:IAO_0000417 ex:PLACEHOLDER_tensile_strength_svs . ex:PLACEHOLDER_tensile_strength_svs a obo:OBI_0001931 ; obo:OBI_0001938 ex:PLACEHOLDER_tensile_strength_value . ex:PLACEHOLDER_tensile_strength_value a qudt:QuantityValue ; qudt:unit unit:MegaPA ; qudt:numericValue ?tensileStrengthValueFinal . # Yield strength: TTO_0000009 ex:PLACEHOLDER_yield_strength a tto:TTO_0000009 ; # yield strength obo:OBI_0001938 ex:PLACEHOLDER_yield_strength_value . ex:PLACEHOLDER_yield_strength_value qudt:numericValue ?yieldStrengthValueFinal ; qudt:unit unit:MegaPA . # Elongation at fracture: TTO_0000033 ex:PLACEHOLDER_elongation a tto:TTO_0000033 ; obo:OBI_0001938 ex:PLACEHOLDER_elongation_value . ex:PLACEHOLDER_elongation_value qudt:numericValue ?elongationAfterFractureValueFinal ; qudt:unit unit:PERCENT . } } WHERE { GRAPH <urn:graph:mfgx-aas> { # Resolve AAS semanticId → property value OPTIONAL { ?tensileStrengthProp a aas:Property ; ns1:value ?tensileStrengthValue ; ns5:semanticId ?tensileStrengthSS . ?tensileStrengthSS ns3:keys ?tensileStrengthKey . ?tensileStrengthKey ns2:value "https://admin-shell.io/idta/…/TensileStrengthMean/1/0" . } BIND(COALESCE(?tensileStrengthValue, "N/A") AS ?tensileStrengthValueFinal) /* … analogous OPTIONAL blocks for yield strength (276) and elongation (60); chemical composition mass fractions (C=0.022, Cr=16.9, Mn=1.51, Mo=2.01, N=0.024, Ni=10, P=0.036, S=0.002, Si=0.4) are written to urn:graph:mfgx as pmd:PMD_0025997 fraction individuals linked via obo:OBI_0001937 … */ } }View full SPARQL on data portal ↗
The INSERT writes into urn:graph:mfgx a graph where a material entity holds the steel qualities via
obo:RO_0000086 — the same structural pattern as the Catena-X pipeline.
Each quality is linked to an OBI measurement datum which carries a QUDT QuantityValue
with qudt:numericValue. Because both pipelines land on this shared predicate
chain, the cross-dataspace query can traverse both graphs with a single path — no UNION.
@prefix obo: <http://purl.obolibrary.org/obo/> . @prefix qudt: <https://qudt.org/schema/qudt/> . @prefix tto: <https://w3id.org/pmd/tto/> . # Material entity (linked from component in assembly graph) <http://www.example.org/#316-4401_material> rdfs:label "Steel 316/4401" ; obo:RO_0000086 <…/tensile_strength_quality>, <…/yield_strength_quality>, <…/elon_af_quality> . # Tensile strength quality — typed with TTO class <…/tensile_strength_quality> a tto:TTO_0000053 ; # tensile strength obo:IAO_0000417 <…/tensile_strength_datum> . <…/tensile_strength_datum> a obo:OBI_0001931 ; obo:OBI_0001938 <…/tensile_strength_qv> . <…/tensile_strength_qv> qudt:numericValue "632" . # same predicate as Catena-X # Yield strength: TTO_0000009 <…/yield_strength_qv> qudt:numericValue "276" . # Elongation at fracture: TTO_0000033 <…/elon_af_qv> qudt:numericValue "60" .View output TTL on data portal ↗
Because all values from the original AAS document are stored faithfully in
urn:graph:mfgx-aas as AAS-ontology RDF, a SPARQL SELECT can reconstruct
the source data directly from the graph — without consulting the original file.
The demo includes a Manufacturing-X: retrieve source JSON query (KG
Inspector panel) that traverses MechanicalTests and
ChemicalAnalysis SubmodelElementCollection nodes and assembles the values
back into JSON via SPARQL CONCAT aggregation:
# Reconstruct mechanical test results from AAS/RDF staging graph SELECT (CONCAT('{"mechanicalTests":{', ?mechJson, '},"chemicalAnalysis":{', ?chemJson, '}}') AS ?json) FROM <urn:graph:mfgx-aas> WHERE { { SELECT (GROUP_CONCAT(CONCAT('"', ?idShort, '":', ?val) ; SEPARATOR=',') AS ?mechJson) WHERE { ?mech aasRf:idShort "MechanicalTests" ; aasSMC:value ?run . ?run aasSMC:value ?prop . ?prop aasRf:idShort ?idShort ; aasP:value ?val . FILTER(REGEX(?val, '^[0-9]')) } } { SELECT (GROUP_CONCAT(CONCAT('"', ?idShort, '":', ?val) ; SEPARATOR=',') AS ?chemJson) WHERE { ?chem aasRf:idShort "ChemicalAnalysis" ; aasSMC:value ?prop . ?prop aasRf:idShort ?idShort ; aasP:value ?val . FILTER(REGEX(?val, '^[0-9]')) } } }
The reconstructed JSON is automatically asserted against the reference values extracted
from inspectiondocument_316_4401_alloy.json, confirming that the AAS → RDF
conversion preserves all numeric values without loss.