Search code examples
c#.netxmllinqcim

Querying CIM XML in C# with LINQ


I am looking for a way to query CIM XML files with LINQ, in order to speed up my analysis of data and verify the exports from a database containing the elements of electrical network. Since I am a newbie in C#, I guessed that it will be easy to load the CIM XML in console application and based on tag values filter some elements. However, all tutorials that I found so far are straight-forward where elements are named like "Student", "Purchase", etc.

My elements are named like "cim:LoadBreakSwitch", where "cim" is actual address defined in root node.

This way, when I try to select all elements named like "cim:LoadBreakSwitch", I get an exception thrown on Run Time because the name of a element cannot contain colon.

Example of element that I want to select from the CIM XML file:

<cim:LoadBreak rdf:ID="101">
    <cim:ConductingEquipment.phases>A</cim:ConductingEquipment.phases>
    <cim:IdentifiedObject.description>PoleMounted</cim:IdentifiedObject.description>
 </cim:LoadBreak>

When I print in the console the names of all elements with

IEnumerable<XElement> elements = xmlDoc.Elements();

        foreach (var item in elements)
        {
            Console.WriteLine(item.Name);
        }

I get something like "{http://[address from the root node]}LoadBreak".

I don't know if there is possibility to do it, but I am just curious did anyone who is experienced developer had need to do something similar.


Solution

  • Your XML is missing a root element with namespace declarations.

    Here is a conceptual example for you. It shows how to handle namespaces and query XML with them.

    c#

    void Main()
    {
        XDocument xdoc = XDocument.Parse(@"<rdf:RDF xmlns:cim='http://iec.ch/TC57/2008/CIM-schema-cim13#'
                     xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>
                <cim:LoadBreak rdf:ID='101'>
                    <cim:ConductingEquipment.phases>A</cim:ConductingEquipment.phases>
                    <cim:IdentifiedObject.description>PoleMounted</cim:IdentifiedObject.description>
                </cim:LoadBreak>
            </rdf:RDF>");
    
        XNamespace cim = xdoc.Root.GetNamespaceOfPrefix("cim");
        XNamespace rdf = xdoc.Root.GetNamespaceOfPrefix("rdf");
    
        foreach (XElement xelem in xdoc.Descendants(cim + "LoadBreak").Elements())
        {
            Console.WriteLine("{0}: {1}"
                , xelem.Name.LocalName
                , xelem.Value);
        } 
    }
    

    Output

    ConductingEquipment.phases: A
    IdentifiedObject.description: PoleMounted