Object identification¶
URIs as identifiers¶
UUIDs (Universally Unique IDentifier), also known as GUIDs (Globally Unique IDentifier) can be used to identify resources in such a way that the - Identifiers can be independently and uniquely allocated by different authorities. This is a big advantage with the UUID - Identifiers are stable over time and across documents.
If, in addition, the UUID is embedded in a Uniform Resource Name (URN) then the document can be simplified by the elimination of XML base namespace declarations (xml:baseattributes). The URN is a concise, fixed-length, absolute URI.
The stability of identifiers over time also requires the following - An identifier shall be created for any object when its existence become know. Note that objects in a model may or may not represent real physical equipment. - An identifier for an object, e.g. a deleted object, is not allowed to be reused.
The standard for an URN containing a UUID is defined by the Internet Engineering Task Force RFC 4122,
RFC 4122 specifies the syntax of the URN and how the UUID portion following the last colon is allocated. The algorithm is aligned with, and technically compatible with, ISO/IEC 9834-8:2005 Information Technology, "Procedures for the operation of OSI Registration Authorities: Generation and registration of Universally Unique Identifiers (UUIDs) and their use as ASN.1 Object Identifier components" ITU-T Rec. X.667, 2004.
CIMXML elements are identified by a URI. Also other forms than the URI is allowed but not recommended.
A URI can have two forms: - URL - URN
The URL and URN forms have fundamentally different structures, i.e.: - URL form; protocol://authority/path?query#fragment where the protocol in CIMXML is http - URN form: urn:namespace:specification where the namespace in CIMXML is uuid.
The URN specification format is summarized below: - 8 character hex number - a dash "-" - 4 character hex number - a dash "-" - 4 character hex number - a dash "-" - 4 character hex number - a dash "-" - 12 character hex number
where characters are lower case conforming to W3C (ISO 8859/1 8-bit single-byte coded graphic character set known as Latin Alphabet No. 1.
An example of the URN form is shown below:
"urn:uuid:26cc8d71-3b7e-4cf8-8c93-8d9d557a4846"
About rdf:ID and rdf:about¶
A CIMXML element can be identified by two different RDF constructs: - rdf:ID - rdf:about
In RDF the rdf:ID identification has the specific meaning that the identifier is unique within a document while the rdf:about identification means the identifier is unique within a namespace. If the UUID name space urn:uuid is used for the rdf:about identification the identifiers are globally unique. Hence CIMXML promote using rdf:about identification in the UUID namespace for all identifiers.
In the past an rdf:ID meant the introduction of a new resource or object while rdf:about meant a reference to an elsewhere introduced resource or object. This distinction is no longer used. As both are UUIDs they have the same meaning. For backwards compatibility both are allowed but the rdf:about form is the preferred.
Identifiers in the FullModel and DifferenceModel elements shall always use the rdf:about identification in the UUID name space, i.e. starting with "urn:uuid:"
CIMXML element identification¶
Resource identification is so central in RDF that all elements representing objects are identified with a rdf:ID or rdf:about XML attribute. All classes in CIM that inherit IdentifiedObject have the UML object identification attribute IdentifiedObject.mRID. The attribute is implicitly mapped to the rdf:ID/rdf:about XML attribute
A CIMXML document may only use the URN form (see URIs as identifiers) as further described below.
CIMXML files contain XML elements describing CIM objects (ACLineSegments, Substationsetc.). The CIM has lots of association roles that show up as references in the XML elements (typically as rdf:resource or rdf:about attributes). CIM data is exchanged in different CIMXML documents that depend on each other. Some references then cross CIMXML document boundaries. A consequence of this is that the identification of a CIM object must be stable during its life time. Otherwise referencing objects across document boundaries will break.
A common practice in object oriented systems is to assume all objects have an identifier that is unique in space and time which means: - Different objects are assigned different identifiers. - Identifiers once assigned are never reused even if the original object having it is gone.
The URN form as described in URIs as identifiers is used as CIMXML element identification with the following differences - The prefix "urn:uuid:" is replaced by an underscore "_" The underscore avoids a numeric starting character for the non-base part of the identifier. Starting the non-base part of the identifier with a numeric character is invalid RDF. The underscore is added in all cases to simplify parsers, even if the UUID starts with a non-numeric character. - The prefix is defined as an xml:base="urn:uuid:"
Some examples: - rdf:ID="_26cc8d71-3b7e-4cf8-8c93-8d9d557a4846" the rdf:ID form. - rdf:about="#_26cc8d71-3b7e-4cf8-8c93-8d9d557a4846" the hash form. - rdf:about="urn:uuid:26cc8d71-3b7e-4cf8-8c93-8d9d557a4846" the urn:uuid: form.
A receiver compatible with Edition 2 is supposed to be able to process all three forms.
A receiver compatible with Edition 1 is supposed to process the rdf:ID and rdf:about forms.
A producer compatible with Edition 2 should preferably only use the urn:uuid: form but is allowed to continue produce the rdf:ID and rdf:about forms.
A producer compatible with Edition 1 will produce the the rdf:ID and rdf:about forms.
CIM Identifier Parser¶
This namespace contains parsers specifically designed for handling CIM (Common Information Model) data according to IEC 61970-552 standards.
The ICimIdentifierParser interface and its implementation CimIdentifierParser provide comprehensive CIM identifier handling, combining all functionality from: - Parsing and normalization of CIM resource identifiers - Validation of CIM URIs (replaces CimUriValidator functionality) - Format detection and conversion
Core Features¶
Parsing & Conversion¶
ParseId()- Extracts UUID identifier from CIM URI as stringParseGuid()- Extracts GUID identifier from CIM URITryParseId()- Attempts to parse CIM URI and extract UUID as stringTryParseGuid()- Attempts to parse CIM URI and extract as GUID
Validation¶
IsValidCimUri()- Validates CIM URI according to IEC 61970-552IsValidId()- Validates CIM URI for rdf:ID formatIsValidAbout()- Validates CIM URI for rdf:about (URN UUID or hash format)IsValidReference()- Validates CIM URI for rdf:resource referencesIsValidForModel()- Validates CIM URI for FullModel/DifferenceModel XML documents (must be URN UUID)IsValidModelAuthoritySet()- Validates CIM URI for Modeling Authority Set (MAS)IsValidProfile()- Validates CIM URI for CGMES Profiles
Format Detection¶
IsUrnUuidFormat()- Detects URN UUID format (urn:uuid:...)IsHashFormat()- Detects hash/fragment format (#_...)IsRdfIdFormat()- Detects rdf:ID format (_...)IsAbsoluteUriWithFragment()- Detects absolute URI with fragment (http://...#_...)
Extraction¶
ExtractUuid()- Extracts identifier from CIM URI or schema reference (returns UUID for CIM resources, fragment for schema references, or full URI for other absolute URIs)TryExtractUuid()- Attempts to extract UUID, returns success statusExtractRdfId()- Extracts identifier in rdf:ID format with underscore prefix (_uuid)ExtractRdfResourceId()- Extracts or validates rdf:resource reference value (converts rdf:ID or raw UUID to hash format, preserves URN UUID and schema references as-is)
Normalization & Generation¶
Normalize()- Converts any valid format to preferred URN UUID formatGenerateNewId()- Creates new compliant CIM URI in URN UUID format
Usage Examples¶
// Inject the parser
private readonly ICimIdentifierParser _cimParser;
// Parse various formats - all return the same GUID
var guid1 = _cimParser.TryParseGuid("urn:uuid:26cc8d71-3b7e-4cf8-8c93-8d9d557a4846", out var result1);
var guid2 = _cimParser.TryParseGuid("#_26cc8d71-3b7e-4cf8-8c93-8d9d557a4846", out var result2);
var guid3 = _cimParser.TryParseGuid("_26cc8d71-3b7e-4cf8-8c93-8d9d557a4846", out var result3);
var guid4 = _cimParser.TryParseGuid("http://example.org/resource#_26cc8d71-3b7e-4cf8-8c93-8d9d557a4846", out var result4);
// Validate CIM URIs
var isValid = _cimParser.IsValidCimUri("urn:uuid:26cc8d71-3b7e-4cf8-8c93-8d9d557a4846");
// Detect format
var isUrn = _cimParser.IsUrnUuidFormat("urn:uuid:26cc8d71-3b7e-4cf8-8c93-8d9d557a4846"); // true
var isHash = _cimParser.IsHashFormat("#_26cc8d71-3b7e-4cf8-8c93-8d9d557a4846"); // true
var isRdfId = _cimParser.IsRdfIdFormat("_26cc8d71-3b7e-4cf8-8c93-8d9d557a4846"); // true
var isAbsolute = _cimParser.IsAbsoluteUriWithFragment("http://example.org#_uuid"); // true
// Extract identifiers in specific formats
var uuid = _cimParser.ExtractUuid("urn:uuid:26cc8d71-3b7e-4cf8-8c93-8d9d557a4846");
// Result: "26cc8d71-3b7e-4cf8-8c93-8d9d557a4846"
// ExtractUuid also handles various input formats:
// "#_72cb1d28-..." → "72cb1d28-..."
// "_72cb1d28-..." → "72cb1d28-..."
// "urn:uuid:#_72cb1d28-..." → "72cb1d28-..." (absolute URI with CIM fragment)
// Schema references return the fragment: "http://iec.ch/TC57/2013/CIM-schema-cim16#SynchronousMachineKind.generator" → "SynchronousMachineKind.generator"
// Other absolute URIs return as-is: "http://savnw/1" → "http://savnw/1"
var rdfId = _cimParser.ExtractRdfId("urn:uuid:26cc8d71-3b7e-4cf8-8c93-8d9d557a4846");
// Result: "_26cc8d71-3b7e-4cf8-8c93-8d9d557a4846"
// Note: Returns null for schema references (not CIM resource URIs)
var resourceId = _cimParser.ExtractRdfResourceId("urn:uuid:26cc8d71-3b7e-4cf8-8c93-8d9d557a4846");
// Result: "urn:uuid:26cc8d71-3b7e-4cf8-8c93-8d9d557a4846" (URN UUID preserved as-is)
// ExtractRdfResourceId handles various formats:
// "#_uuid" → "#_uuid" (hash format preserved)
// "_uuid" → "#_uuid" (rdf:ID converted to hash)
// "uuid" → "#_uuid" (raw UUID converted to hash)
// "urn:uuid:#_uuid" → "#_uuid" (extracts fragment from absolute URI with CIM fragment)
// Schema references preserved: "http://iec.ch/.../CIM#Type.value" → "http://iec.ch/.../CIM#Type.value"
// Normalize to preferred format
var normalized = _cimParser.Normalize("#_26cc8d71-3b7e-4cf8-8c93-8d9d557a4846");
// Result: "urn:uuid:26cc8d71-3b7e-4cf8-8c93-8d9d557a4846"
// Generate new CIM ID
var newId = _cimParser.GenerateNewId();
// Result: "urn:uuid:..." (new UUID in preferred format)
// Validate for FullModel/DifferenceModel (must be URN UUID format)
var validForModel = _cimParser.IsValidForModel("urn:uuid:26cc8d71-3b7e-4cf8-8c93-8d9d557a4846"); // true
var invalidForModel = _cimParser.IsValidForModel("#_26cc8d71-3b7e-4cf8-8c93-8d9d557a4846"); // false
// Validate for rdf:ID and rdf:about attributes
var validId = _cimParser.IsValidId("_26cc8d71-3b7e-4cf8-8c93-8d9d557a4846"); // true
var validAbout = _cimParser.IsValidAbout("urn:uuid:26cc8d71-3b7e-4cf8-8c93-8d9d557a4846"); // true
var validRef = _cimParser.IsValidReference("#_26cc8d71-3b7e-4cf8-8c93-8d9d557a4846"); // true
Dependency Injection¶
Register the parser in your service collection:
services.AddCimParserServices();
or
services.AddSingleton<ICimIdentifierParser, CimIdentifierParser>();