So today at school I was given a task to create an application to apply convolution over image. I decided to load convolution cores from xml file. But, as this was the first time me working with xml I have no knowledge how to effective parse it.

So here is what I came up with. I know that there is better solution to this.

Xml sample:
<?xml version="1.0" encoding="utf-8" ?>
<convolution_cores>
  <matrix size ="3">
    <row index="0">
      <column>-1</column>
      <column>0</column>
      <column>+1</column>
    </row>
    <row index="1">
      <column>-2</column>
      <column>0</column>
      <column>+2</column>
    </row>
    <row index="2">
      <column>-1</column>
      <column>0</column>
      <column>+1</column>
    </row>
  </matrix>
<convolution_cores>

private void LoadFile(string uri, int size)
{
      var matrices = XElement.Load(uri);

      var matrix = from m in
                   (from a in matrices.Descendants("matrix")
                   where (int)a.Attribute("size") == size
                   select a).Descendants().Descendants()
                  select m.Value;
      
      // there's got to be a shorter/more efficent way to do the below task
      _matrix = new float[size, size];
      var str = matrix.GetEnumerator();
      str.MoveNext();

      for (int i = 0; i < size; i++)
      {
             for (int j = 0; j < size; j++)
            {
                    _matrix[i, j] = float.Parse(str.Current);
                    str.MoveNext();
             }
      }
}

That's actually pretty good. You can turn the XML document into a jagged array of floats, but to my knowledge the only way to turn it into a true 2D matrix is to iterate over the result of the query. Here's my alternate code.

using System;
using System.Linq;
using System.Xml.Linq;

class Program
{
    static void Main()
    {
        string xml = @"<?xml version=""1.0"" encoding=""utf-8"" ?>
<convolution_cores>
  <matrix size =""3"">
    <row index=""0"">
      <column>-1</column>
      <column>0</column>
      <column>+1</column>
    </row>
    <row index=""1"">
      <column>-2</column>
      <column>0</column>
      <column>+2</column>
    </row>
    <row index=""2"">
      <column>-1</column>
      <column>0</column>
      <column>+1</column>
    </row>
  </matrix>
</convolution_cores>";

        int size = 3;
        XDocument document = XDocument.Parse(xml);

        var query = (from m in document.Descendants("matrix")
                    where m.Attribute("size").Value == size.ToString()
                    from row in m.Descendants("row")
                    select row.Descendants("column").Select(val => float.Parse(val.Value)).ToArray()).ToArray();


        float[,] matrix = new float[size, size];

        for (int i = 0; i < query.Length; i++)
        {
            for (int j = 0; j < query[0].Length; j++)
            {
                matrix[i, j] = query[i][j];
            }
        }

        Console.Read();

    }
}

Edit: here's my above query in full query expression syntax rather than my query/lambda hybrid

var query2 = (from m in document.Descendants("matrix")
                      where m.Attribute("size").Value == size.ToString()
                      from row in m.Descendants("row")
                      select
                     (from column in row.Elements("column")
                      select float.Parse(column.Value)).ToArray())
                      .ToArray();

Thank you apegram! I just didn't know how to generate a 2D array from query. Thanks again :)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.