0

I'm writing a C# WinForm application that should read a pre-existant XML file. I need to parse the XML file and build up a data structure to reflect the XML file content. I have some experience in XML serialization an thus I tought to use the .NET XML.Serialization features. I got stuck in a strange XML structure that I'm unable to match within the class (trough attributes, elements and so on):

<sheet number="1" name="/" tstamps="/">
  <title_block>
    <title>ECC Push-Pull</title>
    <company/>
    <rev>0.1</rev>
    <date>Sat 21 Mar 2015</date>
    <source>ecc83-pp.sch</source>
    <comment number="1" value=""/>
    <comment number="2" value=""/>
    <comment number="3" value=""/>
    <comment number="4" value=""/>
  </title_block>
</sheet>

The 'weird' part of this is the list of comments. I'm used to find such 'repeating' items as a result of serialization of a list/array of elements with XmlArray directive. Using such approach anyway would introduce a surrouding tag to include the list of items. In this case how can I 'reflect' this structure? This's the code that I should use (without the 'missing' comments):

[XmlRoot("sheet")]
public class Sheet
{
    [XmlAttribute("number")]
    public int Number { get; }

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

    [XmlAttribute("tstamps")]
    public UInt32 TimeStamps { get; set; }

    [XmlElement]
    public SheetTitle Title { get; set; }

    public Sheet()
    {
        Title = new SheetTitle();
    }
}


[XmlRoot("title_block")]
public class SheetTitle
{
    [XmlElement("title")]
    public string Title { get; set; }

    [XmlElement("company")]
    public string Company { get; set; }

    [XmlElement("rev")]
    public string Revision { get; set; }

    [XmlElement("date")]
    public DateTime Date { get; set; }

    [XmlElement("source")]
    public string Source { get; set; }

    public SheetTitle()
    {
        Date = DateTime.Now;
    }
}

[XmlRoot("comment")]
public class Comment
{
    [XmlAttribute("number")]
    public int Number { get; set; }

    [XmlAttribute("value")]
    public string Value { get; set; }
}

I have another side question. The best class hierarchy to reflect this structure is: a) nesting the classes in the same way of the xml elements b) keep all classes at the same level (without a hierarchy)? There are side effects to keep into account ?

2
  • We hope that your issue has been solved. If not, maybe think about updating your question.... meta.stackexchange.com/questions/5234/… Commented Apr 15, 2016 at 20:55
  • been out for holiday I'm going to check it soon Commented Apr 17, 2016 at 18:53

2 Answers 2

2

Try this...

Usings

using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Serialization;

Classes

[XmlRoot(ElementName = "comment")]
public class Comment
{
    [XmlAttribute(AttributeName = "number")]
    public string Number { get; set; }
    [XmlAttribute(AttributeName = "value")]
    public string Value { get; set; }
}

[XmlRoot(ElementName = "title_block")]
public class Title_block
{
    [XmlElement(ElementName = "title")]
    public string Title { get; set; }
    [XmlElement(ElementName = "company")]
    public string Company { get; set; }
    [XmlElement(ElementName = "rev")]
    public string Rev { get; set; }
    [XmlElement(ElementName = "date")]
    public string Date { get; set; }
    [XmlElement(ElementName = "source")]
    public string Source { get; set; }
    [XmlElement(ElementName = "comment")]
    public List<Comment> Comment { get; set; }
}

[XmlRoot(ElementName = "sheet")]
public class Sheet
{
    [XmlElement(ElementName = "title_block")]
    public Title_block Title_block { get; set; }
    [XmlAttribute(AttributeName = "number")]
    public string Number { get; set; }
    [XmlAttribute(AttributeName = "name")]
    public string Name { get; set; }
    [XmlAttribute(AttributeName = "tstamps")]
    public string Tstamps { get; set; }
}

Code

try
{
    XmlDocument xmlDoc = new XmlDocument();
    xmlDoc.Load("xml.xml");

    string XML = xmlDoc.InnerXml.ToString();
    byte[] BUFXML = ASCIIEncoding.UTF8.GetBytes(XML);
    MemoryStream ms1 = new MemoryStream(BUFXML);

    XmlSerializer DeserializerPlaces = new XmlSerializer(typeof(Sheet));
    using (XmlReader reader = new XmlTextReader(ms1))
    {
        Sheet dezerializedXML = (Sheet)DeserializerPlaces.Deserialize(reader);

    }// Put a break-point here, then mouse-over dezerializedXML and you should have you values
}
catch (System.Exception)
{
    throw;
}

This code reads your xml from a file (called xml.xml in the application *.exe folder) then dezerialize it to an object called dezerializedXML....

Sign up to request clarification or add additional context in comments.

Comments

1

You could define your C# objects as follows.

[XmlRoot(ElementName="comment")]
public class Comment {
    [XmlAttribute(AttributeName="number")]
    public string Number { get; set; }
    [XmlAttribute(AttributeName="value")]
    public string Value { get; set; }
}

[XmlRoot(ElementName="title_block")]
public class Title_block {
    [XmlElement(ElementName="title")]
    public string Title { get; set; }
    [XmlElement(ElementName="company")]
    public string Company { get; set; }
    [XmlElement(ElementName="rev")]
    public string Rev { get; set; }
    [XmlElement(ElementName="date")]
    public string Date { get; set; }
    [XmlElement(ElementName="source")]
    public string Source { get; set; }
    [XmlElement(ElementName="comment")]
    public List<Comment> Comment { get; set; }
}

[XmlRoot(ElementName="sheet")]
public class Sheet {
    [XmlElement(ElementName="title_block")]
    public Title_block Title_block { get; set; }
    [XmlAttribute(AttributeName="number")]
    public string Number { get; set; }
    [XmlAttribute(AttributeName="name")]
    public string Name { get; set; }
    [XmlAttribute(AttributeName="tstamps")]
    public string Tstamps { get; set; }
}

Now we can use these entities to Deserialize given Xml.

XmlSerializer serializer = new XmlSerializer(typeof(Sheet));

StreamReader reader = new StreamReader(filepath);
var sheet = (Sheet)serializer.Deserialize(reader);
reader.Close();

Check this Demo code

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.