1

This is my XML schema,

<Modules>
    <Module name="Sales" path="../SalesInfo.xml" isEnabled="true" ... >

      ..............
    </Module>

    <Module name="Purchase" path="../PurchaseInfo.xml" isEnabled="true" ... >
      ..............
    </Module>       

        ................
    </Module>

</Modules>

SalesInfo.XML

 <Screens>
      <Screen name="SalesOrder" ........ />
   </Screen>


public class Module
{
    public string Name
    {
        get;
        set;
    }

    public string Type
    {
        get;
        set;
    }
    .....
}

Here the modules and Screens are loaded on Request basis ("On Demand"). So i have to find the particular node when request comes(may be from menu click). Once the node is picked, it need to be converted to particular class. Eg when "sales" request comes, it should picked from XML and that need to converted to "Module" class. As one possible way is

  • Using XPathNavigator and find the Node.
  • Parse the "Finded Node" and convert to Particular class

This is bit complicated. I have to take care of all the attribute and its datatypes.

What i looking for

  • Find the Node
  • Convert the Node to My custom Class (I doesn't want to write code for Parser)

What is the Best approach. I'm working on C# 4.0.

EDIT:

XDocument document = XDocument.Load(path);

XElement mod = document.XPathSelectElement("Modules/Module[@name='PurchaseEnquiry']") as XElement;

  Module purchaseModule = mod as Module; //This won't work, but i want like this.
Mohanavel
  • 1,763
  • 3
  • 22
  • 44
  • 1
    You don't know [XMLSerializer](http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer.aspx) do you? – jcolebrand Dec 28 '10 at 13:59
  • I'm sure OP is more than happy with his new invention of XMLSerializer :) – Pabuc Dec 28 '10 at 14:05
  • @drachenstern, Each file have plenty of Elements, but i need to load very few Elements. I used the XMLSerializerfor loading the Entire content in the File. Is it possible to Pick particular node and can be convertable to Class using XMLSerializer. I need to have lazy load, sure not pre load. – Mohanavel Dec 28 '10 at 14:13
  • 1
    Of course, call XMLSerializer on the node in question, not on the XMLDocument. Or copy those contents to a new XMLDocument if that's giving you fits. Seriously, they're strings that conform to a standard, it's not _that_ hard. And yes, I hate XML with a passion. – jcolebrand Dec 28 '10 at 15:17
  • @drachenstern, Well i take this as one Option. Looking forward for best. Thanks drachenstern. – Mohanavel Dec 28 '10 at 16:03
  • @Mohanavel ~ Also see http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags and http://stackoverflow.com/questions/701166/can-you-provide-some-examples-of-why-it-is-hard-to-parse-xml-and-html-with-a-rege – jcolebrand Dec 28 '10 at 16:18

1 Answers1

1

Well... Not entirely sure what you are looking for here but I'll give it a shot.
You could read the content node by node and deserialize each node to your class like this:

public class XmlDataReader<T> : IEnumerable, IDisposable
{
    private readonly XmlTextReader reader = null;

    public XmlDataReader(string filename)
    {
        reader = new XmlTextReader(filename) {WhitespaceHandling = WhitespaceHandling.None};
        reader.MoveToContent();     // Go to root node.
        reader.Read();              // Go to first child node.
    }

    #region Implementation of IEnumerable

    public IEnumerator GetEnumerator()
    {
        if (reader == null) yield break;
        do
        {
            var ser = new XmlSerializer(typeof (T));
            var subTree = reader.ReadSubtree();
            subTree.MoveToContent();
            var node = ser.Deserialize(subTree);
            subTree.Close();

            yield return node;

            reader.Skip();
        } while (!reader.EOF && reader.IsStartElement());
    }

    #endregion

    #region Implementation of IDisposable

    public void Dispose()
    {
        if (reader != null)
            reader.Close();
    }

    #endregion
}

In your case you could use it like this:

var reader = new XmlDataReader<Module>("data.xml");
foreach (Module node in reader)
{
  ...
}
Sani Huttunen
  • 23,620
  • 6
  • 72
  • 79