Question

I need to parse an XML config file so that my program can read xml commands and respond to them. For example, I need to parse some objects with rules:

  • Select all objects
  • Select some objects
  • Ignore a property in these objects.
  • And so on.

These commands would be coming from an xml file.

This is what my file looks like:

<model name="testModel" AllObjects="false">
   <objectType name="class1" allProperties="true"/>
   <objectType name="class2" allProperties="false">
     <IncludeProperty name="property1"/>
   </model>

So, what method should I use? State machine? Or something else?

I tried to use state machine, but don't fully understand how it works.

I tried creating some states - Init state, AllObjectsTrue, AllObjectsFalse, AllPropertiesTrue, AllPropertiesFalse.

I try to create simple graph of my project. But I'm not sure that it's all right. gliffy diagramm

The code I have so far:

class StateMachine 
{
  private enum State
    {
        INIT, AllObjectsTrue, AllObjectsFalse,
        AllPropertiesTrue, AllPropertiesFalse, EXIT
    }
    private State state;
    void setState(State value)
    {
        switch (state)
        {
            case State.INIT:
                break;
            case State.AllObjectsTrue:
                break;
            case State.AllObjectsFalse:
                break;
            case State.AllPropertiessTrue:
                break;
            case State.AllPropertiessFalse:
                break;

            case State.EXIT:
                break;
        }

    }
    void eventHandler()
    {
        switch (state)
        {
            case State.INIT:
                break;
            case State.AllObjectsTrue:
                break;
            case State.AllObjectsFalse:
                break;
            case State.AllPropertiessTrue:
                break;
            case State.AllPropertiessFalse:
                break;

            case State.EXIT:
                break;
        }
    }
}

But how do I use it? Should I use state machine to this?And if so- did I do this right?

Thank you!

P.S. I need help with the state machine and its logic(or another method to do this). Not Xml parse(just now:) )

Was it helpful?

Solution

Why would you want to reinvent the wheel and write your own XML parsing routines?

All you need are XML Serialization attributes and the CLR's built-in attribute-based serialization/de-serialation. Look at the namespaces:

  • System.Xml
  • System.Xml.Serialization

First, mark up your model class(es) appropriately:

[XmlRoot( "model" )]
public class CommandModel
{
  [XmlAttribute( "name" )]
  public string Name { get; set; }

  [XmlAttribute( "AllObjects" )]
  public bool AllObjects { get; set; }

  [XmlElement( "objectType" )]
  public List<ObjectType> ObjectTypes { get; set; }

}

[XmlRoot( "objectType" )]
public class ObjectType
{
  [XmlAttribute( "name" )]
  public string Name { get; set; }

  [XmlAttribute( "allproperties" )]
  public bool AllProperties { get; set; }

  [XmlElement( "IncludeProperty" )]
  public List<Property> IncludedProperties { get; set; }

}

[XmlRoot( "IncludeProperty" )]
public class Property
{

  [XmlAttribute( "name" )]
  public string Name { get; set; }

}

Then create a method to do your rehydration for you, something like this:

public static T Rehydrate<T>( TextReader textReader )
{
  XmlSerializer serializer = new XmlSerializer( typeof(T) ) ;
  object o = serializer.Deserialize( textReader ) ;
  T instance = (T) o ;
  return instance ;
}

Then invoke it, something like this:

string myDocument = @"
<model name=""testModel"" AllObjects=""false"" >
  <objectType name=""class1"" allProperties=""true"" />
  <objectType name=""class2"" allProperties=""false"" >
    <IncludeProperty name=""property1""/>
  </objectType>
</model>
" ;

CommandModel model ;
using ( StringReader reader = new StringReader(myDocument) )
{
  model = Rehydrate<CommandModel>( reader ) ;
}

That's about all there is to it. Serializing a model to Xml isn't much more complicated. Something like this will do you:

public static string Dehydrate<T>( T instance )
{
  XmlSerializer serializer = new XmlSerializer(typeof(T));
  StringBuilder sb = new StringBuilder() ;
  using ( StringWriter writer = new StringWriter( sb ) )
  {
    serializer.Serialize(writer,instance) ;
  }
  string xml = sb.ToString() ;
  return xml ;
}

Though you might want to create appropriate XMLWriter and XMLReader instances configured to pretty-print the resulting XML and to read your XML the way you want it read.

OTHER TIPS

You don't need your own XML parser. You need LINQ to XML.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top