2

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

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

谢谢,

埃森

4

3 回答 3

3

进一步了解威廉的帖子:

这将生成 XSD(不是数据集

xsd.exe myCustom.xml

这将生成 C# 类:

xsd.exe myCustom.xsd /c
于 2012-04-27T19:37:56.923 回答
2

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

xsd.exe myXmlFile.xml

输出myXmlFile.xsd

接下来

xsd.exe myXmlFile.xsd

从 xsd 文件生成类。

于 2012-04-26T15:47:04.903 回答
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; }
    }
  }
}

谢谢,

埃森

于 2012-04-27T15:05:53.290 回答