【问题标题】:How do I parse a XML document into object models?如何将 XML 文档解析为对象模型?
【发布时间】:2019-08-01 00:00:41
【问题描述】:

我需要将一个 xml 文档解析为我创建的对象模型,但我不知道该怎么做,我认为这是因为我对 xml 结构缺乏了解。

我尝试从文档中获取所有元素,并根据我认为它们被调用的属性从每个元素中创建单独的对象。

这是我的 C# 代码:

var manifest = XDocument.Load(theDocument);
var allTheElements = manifest.Descendants();

foreach (var element in allTheElements)
{
     //No idea how to parse each object into individual ManifestModel's
}

public class ManifestModel
{
    public string Version { get; set; }
    public string Resource { get; set; }
    public string Size { get; set; }
    public string Checksum { get; set; }
}

这里是 XML 数据:

<?xml version="1.0" encoding="UTF-8"?>
<manifest version="1.0.0" totalbytes="6131797">
  <source uri="codeapi.io/Game/patches/">
    <file resource="FooGame.sln" size="1125" checksum="530B9F1C2412A6D74EF017919074FD8966E5280D" />
    <file resource=".vs\FooGame\v16\.suo" size="69120" checksum="438976A3681FDD503DB4FBFCBB5D420E9E8838DD" />
  </source>
</manifest>

【问题讨论】:

标签: c# xml


【解决方案1】:

就像我们有用于 JSON 的 json2csharp 一样,我们有用于 XML 的 Xml2Csharp。可能还有很多其他网站会这样做。

粘贴您的 XML,它会生成以下内容:

    [XmlRoot(ElementName="file")]
    public class File {
        [XmlAttribute(AttributeName="resource")]
        public string Resource { get; set; }
        [XmlAttribute(AttributeName="size")]
        public string Size { get; set; }
        [XmlAttribute(AttributeName="checksum")]
        public string Checksum { get; set; }
    }

    [XmlRoot(ElementName="source")]
    public class Source {
        [XmlElement(ElementName="file")]
        public List<File> File { get; set; }
        [XmlAttribute(AttributeName="uri")]
        public string Uri { get; set; }
    }

    [XmlRoot(ElementName="manifest")]
    public class Manifest {
        [XmlElement(ElementName="source")]
        public Source Source { get; set; }
        [XmlAttribute(AttributeName="version")]
        public string Version { get; set; }
        [XmlAttribute(AttributeName="totalbytes")]
        public string Totalbytes { get; set; }
    }

人们可以称之为懒惰或作弊,但我看不出编写可以在一秒钟内为我生成的代码的意义。你可能并不总是得到完美的结果,但这是一个很好的起点。例如,它对所有属性类型使用string。如果您期望所有数值,则可以将其替换为 intlong

现在你可以像这样反序列化:

var serializer = new XmlSerializer(typeof(Manifest), new XmlRootAttribute("manifest"));
using (var stream = System.IO.File.OpenRead("test.xml"))
{
    var deserialized = (Manifest)serializer.Deserialize(stream);
}

一旦您将数据反序列化为 something,剩下的就容易多了。您可以使用自动生成的模型或将它们映射到您自己的模型。

【讨论】:

    【解决方案2】:

    使用 LINQ...

    c#

    void Main()
    {
        string fileName = @"e:\Temp\GamePatches.xml";
    
        XDocument manifest = XDocument.Load(fileName);
        string version = manifest.Root.Attribute("version").Value;
    
        List<ManifestModel> manifestModel = new List<ManifestModel>();
    
        foreach (XElement e in manifest.Descendants("file"))
        {
            manifestModel.Add(new ManifestModel() { Version = version
                    , Resource = (string)e.Attribute("resource").Value 
                    , Size = (string)e.Attribute("size").Value 
                    , Checksum = (string)e.Attribute("checksum").Value }
                    );
        }
    }
    
    // Define other methods and classes here
    public class ManifestModel
    {
        public string Version { get; set; }
        public string Resource { get; set; }
        public string Size { get; set; }
        public string Checksum { get; set; }
    }
    

    【讨论】:

      【解决方案3】:

      我花了很多时间开发一个通过 XML Schema 解析的类似应用程序,我发现最简单的方法是将 XML 文档转换为 XmlNodeList。从这里您可以使用 SelectNodes 和 SelectSingleNodes 在其中导航。看看这个:https://docs.microsoft.com/en-us/dotnet/api/system.xml.xmlnode.selectnodes?view=netframework-4.8,但基本上你要做的是创建一个 xpath 字符串来选择你需要的节点。以下是一些相关文档:https://docs.microsoft.com/en-us/dotnet/standard/data/xml/select-nodes-using-xpath-navigation

      【讨论】:

        猜你喜欢
        • 2015-09-12
        • 2012-07-14
        • 1970-01-01
        • 2012-02-11
        • 1970-01-01
        • 2011-07-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多