2

Is there an easy way to construct class from a XML. The constructed class will be used to serialize and deserialize XML.

I have an XML with lots of properties and elements defined. Do I need to manually create my class based on that XML? Or Is there a utility tool available to generate class from XML

Thanks,

Esen

2
  • What language/platform are you using to construct your class? Commented Apr 26, 2012 at 14:54
  • Sorry for not being clear. I am looking into Microsoft.NET (VB.NET or C#.NET) Commented Apr 26, 2012 at 15:31

3 Answers 3

3

Further on Willem's post:

This will generate the XSD (not dataset)

xsd.exe myCustom.xml

This generates the C# class:

xsd.exe myCustom.xsd /c
Sign up to request clarification or add additional context in comments.

1 Comment

what is the generated C# class? Isn't it a dataset? I didn't get you code4life
2

There's a round about way: Using xsd.exe, you can first create a schema (xsd) from your xml file, which can then be used as input for xsd.exe to generate classes from the schema. i.e. (from the command prompt):

xsd.exe myXmlFile.xml

to output myXmlFile.xsd

and next

xsd.exe myXmlFile.xsd

to generate classes from the xsd file.

1 Comment

This doesn't provide straight forward result what I am looking for. But this hint is helpful. I could generate dataset then from there I can generate the class that I am looking for. Thanks for your help Rumpt.
1

@Willem van Rumpt: solution helped me to generate class. But in some case when I try to instantiate the dataset, I end up receiving this exception "Same Table cannot be the child table in two nested relations..."

I have tried different solution using xmldocument object to navigate each nodes and generate my class that can be used to serialize and deserialize xml file. Thought to post it here so that it would be helpful to someone who is looking for similar solution. Please post your optimized solution if you have one.

namespace Utility1 
{
public static class XMLHelper
{
   private enum XMLType
   {
      Element,
      Attribute
   }
    public static string GenerateXMLClass(string xmlstring)
    {
        XmlDocument xd = new XmlDocument();
        xd.LoadXml(xmlstring);
        XmlNode rootNode = xd.DocumentElement;
        var xmlClassCollection = new Dictionary<string, XMLClass>();
        var xmlClass = new XMLClass();
        xmlClassCollection.Add(rootNode.Name, xmlClass);
        CollectAttributes(ref xmlClass, rootNode);
        CollectElements(ref xmlClass, rootNode);
        CollectChildClass(ref xmlClassCollection, rootNode);

        var clsBuilder = new StringBuilder();

        clsBuilder.AppendLine("[XmlRoot(\"" + rootNode.Name + "\")]");

        foreach (var cls in xmlClassCollection)
        {
            clsBuilder.AppendLine("public class " + cls.Key);
            clsBuilder.AppendLine("{");

            foreach (var element in cls.Value.Elements)
            {
                if (XMLType.Element == element.XmlType)
                    clsBuilder.AppendLine("[XmlElement(\"" + element.Name + "\")]");
                else
                    clsBuilder.AppendLine("[XmlAttribute(\"" + element.Name + "\")]");
                clsBuilder.AppendLine("public " + element.Type + element.Name + "{get;set;}");
            }

            clsBuilder.AppendLine("}");
        }

        return clsBuilder.ToString();
    }

    private static void CollectAttributes(ref XMLClass xmlClass, XmlNode node)
    {
        if (null != node.Attributes)
        {
            foreach (XmlAttribute attr in node.Attributes)
            {
                if (null == xmlClass.Elements.SingleOrDefault(o => o.Name == attr.Name))
                    xmlClass.Elements.Add(new Element("string ", attr.Name, XMLType.Attribute));
            }
        }
    }

    private static bool IsEndElement(XmlNode node)
    {
        if ((null == node.Attributes || node.Attributes.Count <= 0) &&
                   (null == node.ChildNodes || !node.HasChildNodes || (node.ChildNodes.Count == 1 && node.ChildNodes[0].NodeType == XmlNodeType.Text)))
        {
            return true;
        }
        return false;
    }

    private static void CollectElements(ref XMLClass xmlClass, XmlNode node)
    {
        foreach (XmlNode childNode in node.ChildNodes)
        {
            if (null == xmlClass.Elements.SingleOrDefault(o => o.Name == childNode.Name))
            {
                var occurance = node.ChildNodes.Cast<XmlNode>().Where(o => o.Name == childNode.Name).Count();
                var appender = "  ";
                if (occurance > 1)
                    appender = "[] ";

               if(IsEndElement(childNode))
                {
                    xmlClass.Elements.Add(new Element("string" + appender, childNode.Name, XMLType.Element));
                }
                else
                {
                    xmlClass.Elements.Add(new Element(childNode.Name + appender, childNode.Name, XMLType.Element));
                }
            }
        }
    }

    private static void CollectChildClass(ref Dictionary<string, XMLClass> xmlClsCollection, XmlNode node)
    {
        foreach (XmlNode childNode in node.ChildNodes)
        {
            if (!IsEndElement(childNode))
            {
                XMLClass xmlClass;
                if (xmlClsCollection.ContainsKey(childNode.Name))
                    xmlClass = xmlClsCollection[childNode.Name];
                else
                {
                    xmlClass = new XMLClass();
                    xmlClsCollection.Add(childNode.Name, xmlClass);
                }
                CollectAttributes(ref xmlClass, childNode);
                CollectElements(ref xmlClass, childNode);
                CollectChildClass(ref xmlClsCollection, childNode);
            }
        }
    }

    private class XMLClass
    {
        public XMLClass()
        {
            Elements = new List<Element>();
        }
        public List<Element> Elements { get; set; }
    }

    private class Element
    {
        public Element(string type, string name, XMLType xmltype)
        {
            Type = type;
            Name = name;
            XmlType = xmltype;
        }
        public XMLType XmlType { get; set; }
        public string Name { get; set; }
        public string Type { get; set; }
    }
  }
}

thanks,

Esen

2 Comments

By the way this will create class with string properties. Need to validate the value and assign appropriate property type.
I have to say that I would personally stay clear of roll-your-own solutions to this problem (given the many (MANY) pitfalls); if it works for you: Great :)

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.