Skip to content

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:
    1. rdf:ID and rdf:about use non-standard URI formats (e.g., _123 instead of proper URIs)
    2. rdf:parseType="Statements" was introduced but is not valid W3C RDF/XML syntax
    3. 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"

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