1

I found this code on this Microsoft page: Microsoft Dynamic XML Parser

 public string this[string dbName]
    {
        get
        {
            return xmlSQL.Attribute(dbName).Value;
        }
    }

i would like to use this funcionality but instead of just returning an object like in the Microsoft example i like to receive a predefined Type.

DynamicXmlParser parser = new DynamicXmlParser(@".\order.xml");
int s = parser.element;

and my intellisense and the compiler knows what he will get.

Noel Schenk
  • 724
  • 1
  • 8
  • 19

3 Answers3

2

I changed L.B's answer about DynamicXml here a little bit

public class DynamicXmlExt : DynamicObject
{
    XElement _root;
    private DynamicXmlExt(XElement root)
    {
        _root = root;
    }

    public static DynamicXmlExt Parse(string xmlString)
    {
        return new DynamicXmlExt(XDocument.Parse(xmlString).Root);
    }

    public static DynamicXmlExt Load(string filename)
    {
        return new DynamicXmlExt(XDocument.Load(filename).Root);
    }

    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        result = null;

        var att = _root.Attribute(binder.Name);
        if (att != null)
        {
            result = att;
            return true;
        }

        var nodes = _root.Elements(binder.Name);
        if (nodes.Count() > 1)
        {
            result = nodes.Select(n => new DynamicXmlExt(n)).ToList();
            return true;
        }

        var node = _root.Element(binder.Name);
        if (node != null)
        {
            if (node.HasElements)
            {
                result = new DynamicXmlExt(node);
            }
            else
            {
                result = node;
            }
            return true;
        }

        return true;
    }
}

Now You can cast the values to desired types like (using the same xml example):

string xml = @"<Students>
            <Student ID=""100"">
                <Name>Arul</Name>
                <Mark>90</Mark>
            </Student>
            <Student>
                <Name>Arul2</Name>
                <Mark>80</Mark>
            </Student>
        </Students>";

dynamic students = DynamicXmlExt.Parse(xml);

int id = (int)students.Student[0].ID;
int mark = (int)students.Student[0].Mark;
string name = (string)students.Student[1].Name; 
Community
  • 1
  • 1
Eser
  • 12,346
  • 1
  • 22
  • 32
0

You can create a generic getAttribute method that will use a cast, however that will not always work. In particular it will fail when the input string is not formatted according to the regional standards of the running thread Thread.CurrentCulture

Your code could be something like this

public T Get<T>() { return (T)xmlSQL.Attribute(dbName).Value; }

Note, that C# does not support generic indexers, so you have to revert to using a method

Also note you might prefer using Nullable<T> for value types - i.e. int? instead of int to account for cases where there is no value, see this link

ironstone13
  • 3,325
  • 18
  • 24
0

A dynamic object won't be able to show you at compile time information that won't be known until run time (like the type of element you are retrieving). The point of dynamics is to deal with objects that aren't understood by the compiler but whose runtime properties are understood by the developer. Visual Studio doesn't know what kind of data is in your XML document because the XML document isn't read until the application is run.

If you want to deal with XML in a strongly-typed fashion, then you should consider XML serialization. You can write classes that model arbitrary XML documents and control the manner in which they are mapped using attributes. See https://msdn.microsoft.com/en-us/library/2baksw0z(v=vs.110).aspx for more information.

DVK
  • 2,726
  • 1
  • 17
  • 20