Tuesday, March 1, 2011

LINQ to XML: parsing XML file which one of nodes presents type of another node

Helo!

Is this possible to use string value of one node which tells what type of field is presented in another node using LINQ to XML?

For example:

<node>
  <name>nodeName</name>
  <type>string</type>
</node>
<node>
  <name>0</name>
  <type>bool</type>
</node>
<node>
  <name>42</name>
  <type>int</type>
</node>

Thanks in advance

From stackoverflow
  • Well, you won't get a nice statically typed API given that the type information is only known at execution time - but you could easily write an extension method on XElement which looks for the appropriate subelements and returns System.Object. For instance (untested):

    public static object ParseValue(this XElement element)
    {
        XElement name = element.Element("name");
        XElement type = element.Element("type");
        // Insert error handling here :)
    
        switch (type.Value)
        {
            case "int":
                return int.Parse(name.Value);
            case "string":
                return name.Value;
            case "bool":
                return name.Value == "1"; // Or whatever
            default:
                throw new ArgumentException("Unknown element type " + type.Value);
        }
    }
    

    It's not how I'd design a data format, but if it's being thrust upon you...

  • public static void Main() {
     var xmlNodes = new XElement( "Nodes",
      new XElement( "Node",
       new XElement( "Name", "nodeName" ),
       new XElement( "Type", "string" )
      ),
      new XElement( "Node",
       new XElement( "Name", "True" ),
       new XElement( "Type", "bool" )
      ),
      new XElement( "Node",
       new XElement( "Name", "42" ),
       new XElement( "Type", "int" )
      )
     );
    
     var converters = new Dictionary<string,Func<string,object> >  {
      { "string", val => val },
      { "bool", val => Boolean.Parse( val ) },
      { "int", val => Int32.Parse( val ) }
     };
    
     var values = 
      from node in xmlNodes.Elements( "Node" )
      select converters[ node.Element( "Type" ).Value ]( node.Element( "Name" ).Value );
    
     foreach( var value in values )
      Console.WriteLine( value.GetType().ToString() + ": " + value );
    }
    

0 comments:

Post a Comment