You can easily read this data with xml serialization. I can show you how to do it with a couple of simple classes using xml attributes.
But first, I need to ask if you have the ability to alter the xml schema. Your existing xml snippet has some inconsistencies. Can you modifiy that or is it fixed?
You can easily read this data with xml serialization. I can show you how to do it with a couple of simple classes using xml attributes.
But first, I need to ask if you have the ability to alter the xml schema. Your existing xml snippet has some inconsistencies. Can you modify that or is it fixed?
What are the inconsistencies? If you're talking about the data between the membership tags then this is exactly the challenge with this problem.
What are the inconsistencies? If you're talking about the data between the membership tags then this is exactly the challenge with this problem.
Well you've got different casing within the tags. Usually xml tags are pascal case (start with a capital letter) or camel case (start with a lower case letter). You can certainly have a mix but it's a bit odd.
As far as 'collection' element inside the 'Membership' element... that's okay, but the opening tag must exactly match the closing tag. You have <collection>...</Collection> and that isn't valid xml.
Well you've got different casing within the tags. Usually xml tags are pascal case (start with a capital letter) or camel case (start with a lower case letter). You can certainly have a mix but it's a bit odd.
As far as 'collection' element inside the 'Membership' element... that's okay, but the opening tag must exactly match the closing tag. You have <collection>...</Collection> and that isn't valid xml.
You're correct, I have made up the example but the actual data does follow the same concept that you outlined above. I originally shredded the XML in SQL but the unpredictability of the membership tag is painful to manipulate. Thanks for everything!
Next the serialization classes. The Data class is the 'root' class that contains a static Load method. This loads the xml file into a reader, then deserializes it into the Data (and other) class instances.
Code:
using System;
using System.Collections.Generic;
using System.Xml;
using System.Xml.Serialization;
namespace CG.MultiLevelXml.Serialization
{
public enum Status
{
Achieved = 0,
Terminated = 1,
Valid = 2
}
[XmlType(AnonymousType = true)]
[XmlRoot(ElementName = "data", Namespace = "", IsNullable = false)]
public class Data
{
public static Data Load(string xmlFile)
{
var serializer = new XmlSerializer(typeof (Data));
using( var reader = XmlReader.Create(xmlFile))
{
return (Data) serializer.Deserialize(reader);
}
}
/// <summary>
/// Drive list
/// </summary>
/// <remarks>
/// No te: Use a generic collection here to 'back' the drive array.
/// That way client code won't have to check for Drives == null
/// </remarks>
[XmlElement( "drive" )]
public Drive[] Drives
{
get
{
if( _driveList == null )
{
_driveList = new List<Drive>();
}
return _driveList.ToArray();
}
set
{
if ( _driveList == null )
{
_driveList = new List<Drive>( );
}
if(value != null)
{
_driveList.AddRange(value);
}
}
}
private List<Drive> _driveList = new List<Drive>();
}
public class Drive
{
[XmlElement("label")]
public string Label { get; set; }
[XmlElement( "date" )]
public string Date { get; set; }
[XmlElement("description")]
public string Description { get; set; }
[XmlElement( "status" )]
public Status Status { get; set; }
[XmlElement( "membership" )]
public Membership Membership { get; set; }
/// <summary>
/// Use this property to retrieve the MemberShip or Collection value
/// </summary>
[XmlIgnore]
public string MembershipValue
{
get
{
return IsCollection ? Membership.Collection.Value : Membership.Value;
}
}
/// <summary>
/// Use this property to determine if Membership or Collection
/// </summary>
[XmlIgnore]
public bool IsCollection
{
get
{
return (Membership != null && Membership.Collection != null);
}
}
/// <summary>
/// Override to format an output string
/// </summary>
/// <returns></returns>
public override string ToString( )
{
return String.Format("{0,-15}{1,-15}{2,-30}{3,-12}{4,-14}{5}", Label, Date, Description, Status, IsCollection, MembershipValue);
}
}
public class Membership
{
[XmlText]
public string Value { get; set; }
[XmlElement( "collection", IsNullable = true)]
public Collection Collection { get; set; }
}
public class Collection
{
[XmlText]
public string Value { get; set; }
}
}
Finally, using the class...
Code:
using System;
using CG.MultiLevelXml.Serialization;
namespace CG.MultiLevelXml
{
class Program
{
static void Main( string [ ] args )
{
var data = Data.Load("data.xml");
Console.WriteLine( "{0,-15}{1,-15}{2,-30}{3,-12}{4,-14}{5}\n", "Label", "Date", "Description", "Status", "IsCollection", "MembershipValue" );
foreach(var drive in data.Drives)
{
Console.WriteLine(drive);
}
}
}
}
Output:
Code:
Label Date Description Status IsCollection MembershipValue
Area 51 12/10/2012 testing site Valid False
Username="Jsmith"
Bool="or"
username="MGordon"
Apollo 12/04/2010 fly to the Moon Terminated False
Username="DKerr"
bool="and"
Username="Sremi"
bool="or"
Group="ApolloReadOnly"
Deep Impact 12/06/08 Exploring Comet Temple Achieved True
Username="Gblaine"
Group="SSnype"
group="Wesson"
bool="or"
Computer="Exec-02"
* The Best Reasons to Target Windows 8
Learn some of the best reasons why you should seriously consider bringing your Android mobile development expertise to bear on the Windows 8 platform.