質問

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:) )

役に立ちましたか?

解決

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.

他のヒント

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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top