Is it possible to load DGML file with the function of XDocument like loading XML file?

231 views Asked by At

I would like to load DGML file to a C# code like loading XML files. How should I write to load them?

I could not find good examples about DGML file loader, however, I found XML file loader examples. So I've tried to load DGML files like loading XML files using XDocument function.

This is a function I made and it works to XML files. But DGML files could not load properly.

string DGMLFileName = "test.dgml"

if (!DGMLFileName.Contains(".dgml"))
    DGMLFileName += ".dgml";

string text = ReadString(DGMLFileName);

if (text == "")
{
    DebugLog("DGML not found or empty");
    return null;
}

if (text.StartsWith("<?xml"))
{
    text = text.Substring(text.IndexOf("?>") + 2);
}

DebugLog("DGML text ... " + text);

XDocument doc = XDocument.Parse(text);
var root = doc.Elements("DirectedGraph");
var elements = root.Elements("Nodes").Elements("Node");

foreach (var item in elements)
{
    var name = item.Attribute("Id").Value;
}


In this code, elements are empty. What I tried to load is this kind of simple DGML files. "https://learn.microsoft.com/en-us/visualstudio/modeling/directed-graph-markup-language-dgml-reference?view=vs-2019"

<?xml version="1.0" encoding="utf-8"?>
<DirectedGraph Title="DrivingTest" xmlns="http://schemas.microsoft.com/vs/2009/dgml">
   <Nodes>
      <Node Id="Driver" Label="Driver" Category="Person" DrivingAge="18"/>
      <Node Id="Car" Label="Car" Category="Automobile" />
      <Node Id="Truck" Label="Truck" Category="Automobile" />
      <Node Id="Passenger" Category="Person" />
   </Nodes>
   <Links>
      <Link Source="Driver" Target="Car" Label="Passed" Category="PassedTest" />
      <Link Source="Driver" Target="Truck" Label="Failed" Category="FailedTest" />
   </Links>
   <Categories>
      <Category Id="Person" Background="Orange" />
      <Category Id="Automobile" Background="Yellow"/>
      <Category Id="PassedTest" Label="Passed" Stroke="Black" Background="Green" />
      <Category Id="FailedTest" Label="Failed" BasedOn="PassedTest" Background="Red" />
   </Categories>
   <Properties>
       <Property Id="DrivingAge" Label="Driving Age" DataType="System.Int32" />
   </Properties>
</DirectedGraph>

What is the incorrect part of my code?

Thanks,

2

There are 2 answers

2
Denis Schaf On BEST ANSWER

it seems to me the XML parser does not like the xmlns of the file try replacing this:

<DirectedGraph Title="DrivingTest" xmlns="http://schemas.microsoft.com/vs/2009/dgml">

with

<DirectedGraph Title="DrivingTest" xmlns:xsd="http://www.w3.org/2001/XMLSchema">

now your xml parser will be able to read the file in your code you need to manipulate your variable text wit a string.Replace() for example

i tested the following XML:

<?xml version="1.0" encoding="utf-8"?>
<DirectedGraph Title="DrivingTest" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   <Nodes>
      <Node Id="Driver" Label="Driver" Category="Person" DrivingAge="18"/>
      <Node Id="Car" Label="Car" Category="Automobile" />
      <Node Id="Truck" Label="Truck" Category="Automobile" />
      <Node Id="Passenger" Category="Person" />
   </Nodes>
   <Links>
      <Link Source="Driver" Target="Car" Label="Passed" Category="PassedTest" />
      <Link Source="Driver" Target="Truck" Label="Failed" Category="FailedTest" />
   </Links>
   <Categories>
      <Category Id="Person" Background="Orange" />
      <Category Id="Automobile" Background="Yellow"/>
      <Category Id="PassedTest" Label="Passed" Stroke="Black" Background="Green" />
      <Category Id="FailedTest" Label="Failed" BasedOn="PassedTest" Background="Red" />
   </Categories>
   <Properties>
       <Property Id="DrivingAge" Label="Driving Age" DataType="System.Int32" />
   </Properties>
</DirectedGraph>

With this code:

    void ReadXML()
    {
        XDocument doc = XDocument.Load("tmp.xml");
        var root = doc.Elements("DirectedGraph");
        var elements = root.Elements("Nodes").Elements("Node");

        foreach (var item in elements)
        {
            var name = item.Attribute("Id").Value;
        }
    }

I can imagine you do not want to manipulate the file as its a standard format so just maipulate the textvariable in your code before passing it into the parser

2
Bart de Boer On

In fact, it's not about the xml parser not LIKING the namespace, it's you not requesting the correct element name.

You 'simply' need to include the namespace on the element name you're querying:

XNamespace dgmlNs = "http://schemas.microsoft.com/vs/2009/dgml";
var doc = XDocument.Load("file.dgml");
var nodeElements = doc.Root.Elements( dgmlNs+"Nodes").Elements( dgmlNs+"Node");

This will actually give you results.

To reduce tediousness of this (and improve readability):

XName nodesName = dgmlNs + "Nodes";
XName nodeName = dgmlNs + "Node";
var nodes = doc.Root.Elements( nodesName ).Elements( nodeName );