用于序列化的XML类生成器

时间:2012-04-26 14:46:08

标签: c# vb.net xml-serialization auto-generate

是否有一种从XML构造类的简单方法。构造的类将用于序列化和反序列化XML。

我有一个XML,其中定义了许多属性和元素。我是否需要根据该XML手动创建我的类?或者是否有可用于从XML生成类的实用工具

谢谢,

也先

3 个答案:

答案 0 :(得分:3)

进一步关于威廉的帖子:

这将生成XSD(非数据集

xsd.exe myCustom.xml

这会生成C#类:

xsd.exe myCustom.xsd /c

答案 1 :(得分:2)

有一个回合路: 使用xsd.exe,您可以先从xml文件创建一个模式(xsd),然后可以将其用作xsd.exe的输入,以便从模式生成类。 即(来自命令提示符):

xsd.exe myXmlFile.xml

输出myXmlFile.xsd

和下一个

xsd.exe myXmlFile.xsd

从xsd文件生成类。

答案 2 :(得分:1)

@Willem van Rumpt:解决方案帮我生成课程。但在某些情况下,当我尝试实例化数据集时,我最终收到此异常“同一个表不能是两个嵌套关系中的子表...”

我尝试过使用xmldocument对象导航每个节点并生成可用于序列化和反序列化xml文件的类的不同解决方案。想在这里发布它,以便对寻找类似解决方案的人有所帮助。如果您有优化的解决方案,请发布。

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; }
    }
  }
}

感谢,

也先