1

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://docs.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,

Masahiro
  • 125
  • 8

2 Answers2

2

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 );
Bart de Boer
  • 126
  • 4
1

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

Denis Schaf
  • 1,912
  • 1
  • 5
  • 14