用于序列化的 XML 类生成器

本文关键字:XML 序列化 用于 | 更新日期: 2023-09-27 18:32:24

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

我有一个定义了大量属性和元素的 XML。我是否需要基于该 XML 手动创建类?或者是否有可用于从 XML 生成类的实用程序

谢谢

埃森

用于序列化的 XML 类生成器

进一步了解威廉的帖子:

这将生成 XSD(不是数据集

xsd.exe myCustom.xml

这将生成 C# 类:

xsd.exe myCustom.xsd /c

有一个关于方法的方法:使用 xsd.exe ,您可以首先从 xml 文件创建架构 (xsd),然后可以将其用作xsd.exe从架构生成类的输入。即(从命令提示符):

xsd.exe myXmlFile.xml

输出myXmlFile.xsd

和下一个

xsd.exe myXmlFile.xsd

从 XSD 文件生成类。

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

谢谢

埃森