CGMES/CIMXML Gaps¶
1. Non-Standard RDF/XML Serialization (CIMXML)¶
Root Cause Analysis¶
IEEE published CIMXML in 2003, but W3C RDF/XML 1.0 was finalized in 2004 → CIMXML was based on a draft specification.
- Technical Issues:
rdf:IDandrdf:aboutuse non-standard URI formats (e.g., _123 instead of proper URIs)rdf:parseType="Statements"was introduced but is not valid W3C RDF/XML syntax- Multiple graphs in one file violates standard RDF/XML structure
Standard RDF libraries (Apache Jena, rdflib, etc.) cannot parse CIMXML correctly without custom modifications.
How We Solved It¶
In DifferenceModelReader.cs:
// MANUAL HANDLING OF rdf:parseType="Statements"
private string WrapInRdfDocument(string xmlContent, IGraph parentGraph)
{
// Reconstruct proper RDF/XML with correct namespaces
return $"<?xml version=\"1.0\" encoding=\"utf-8\"?><rdf:RDF {namespaces}>{xmlContent}</rdf:RDF>";
}
In CimNodeResolver.cs implementations:
// FIX FOR NON-STANDARD URIs
public string GetInstanceId(INode node)
{
var rawId = GetRawValue(node);
// Convert CIMXML's "_123" to proper "urn:uuid:123"
// Create a normalized URI format for consistent processing
return normalizeId
}
2. Missing Datatype Information¶
Root Cause Analysis¶
CIMXML serialization does not include rdf:datatype attributes for literal values.
- Example:
<cim:GeneratingUnit.maxOperatingP>100</cim:GeneratingUnit.maxOperatingP>- Missing:
rdf:datatype="http://www.w3.org/2001/XMLSchema#decimal"
- Missing:
Applications cannot distinguish between strings, numbers, dates, etc., leading to validation errors and incorrect calculations.
How We Solved It¶
Profile-Based Datatype Mapping: Use RDFS/SHACL profiles to infer datatypes:
# RDFS Profile defines datatype
cim:GeneratingUnit.maxOperatingP rdfs:range xsd:decimal .
Runtime Datatype Enhancement:
public class DatatypeMapper
{
public object ParseWithDatatype(string literalValue, string propertyUri, IGraph profileGraph)
{
// Query RDFS/SHACL to get datatype for property
var datatype = GetDatatypeFromProfile(propertyUri, profileGraph);
// Apply correct parsing
return datatype switch
{
"xsd:decimal" => decimal.Parse(literalValue),
"xsd:integer" => int.Parse(literalValue),
"xsd:dateTime" => DateTime.Parse(literalValue),
_ => literalValue // fallback to string
};
}
}
This approach allows us to handle missing datatype information gracefully while maintaining compatibility with standard RDF processing tools.
Integrated in Property Factory:
public class CimPropertyFactory
{
public ICimProperty GetProperty(IGraph graph, Triple triple)
{
var value = NodeResolver.GetRawValue(triple.Object);
var datatype = DatatypeMapper.GetDatatype(triple.Predicate, graph);
return new TypedCimProperty(value, datatype);
}
}
3. No Standard Way to Handle Multiple Profiles/Versions¶
Root Cause Analysis¶
- Complex Ecosystem: CGMES has multiple versions (v2.4.15, v3.0) and profiles (EQ, SSH, TP, SV, etc.)
- Missing Machinery: No standard way to:
- Validate against specific profile versions
- Convert between versions
- Handle backward/forward compatibility
Vendor tools implement different validation rules, causing interoperability failures.
4. Lack of Open, Standardized Tooling¶
Root Cause Analysis¶
- Vendor Lock-in: Each vendor developed proprietary parsers with different interpretations
- Duplicated Effort: 40+ TSOs and their vendors all solving the same problems independently
- No Reference Implementation: IEC/ENTSO-E published standards but no reference code
5. Poor Validation & Debugging Experience¶
Root Cause Analysis¶
- Legacy Validation: Originally used OCL (Object Constraint Language), hard to maintain
- No Standard Validation Reports: Each tool produces different error formats
- Hard to Debug: When validation fails, difficult to trace which profile/rule caused it