解析XML文件并从父节点获取值

时间:2017-12-02 19:57:51

标签: c# .net xml

XML文件如下所示:

<?xml version="1.0"?>
<catalog>
    <book id="bk101">
        <author>Gambardella, Matthew</author>
        <title>XML Developer's Guide</title>
        <genre>Computer</genre>
        <price>44.95</price>
        <publish_date>2000-10-01</publish_date>
        <description>An in-depth look at creating applications with XML.</description>
    </book>
    <book id="bk102">
        <author>Ralls, Kim</author>
        <title>Midnight Rain</title>
        <genre>Fantasy</genre>
        <price>5.95</price>
        <publish_date>2000-12-16</publish_date>
        <description>A former architect battles corporate zombies, an evil sorceress, and her own childhood to become queen of the world.</description>
    </book>
</catalog>

我需要读取所有数据到我的班级:

public class Book
{
    public string Id { get; set; }

    public string Author { get; set; }
    public string Title { get; set; }
    public Genre Genre { get; set; }
    public decimal Price { get; set; }
    public DateTime PublishDate { get; set; }
    public string Description { get; set; }

}

下面的代码不起作用,我可以从节点中获取bookId,但不能获取Title,Author .. 如何实现这一结果?这就是我到目前为止所做的:

const string filePath = @"C:\Users\Michał\Desktop\books.xml";

XDocument xmlDoc = XDocument.Load(filePath);

var dupa = xmlDoc
    .Descendants("book")
    .Select(x => new Book()
    {
        Id = (string) x.Attribute("bookid"),

        Title = (string) x.Attribute("title") // Title is empty after that code runs

    }).ToList();

1 个答案:

答案 0 :(得分:1)

id<book> var dupa = xmlDoc .Descendants("book") .Select(x => new Book { Id = (string)x.Attribute("bookid"), Author = (string)x.Element("author"), Title = (string)x.Element("title"), Genre = (Genre)Enum.Parse(typeof(Genre), (string)x.Element("genre")), Price = (decimal)x.Element("price"), PublishDate = (DateTime)x.Element("publish_date"), Description = (string)x.Element("description"), }).ToList(); ,但其他节点是子XML attribute,因此您需要使用elements访问它们:

Genre

这里我假设public enum Genre { Computer, Fantasy, }; 是一个类似于:

的枚举
Catalog

示例XContainer.Element(XName name)

或者,您可以创建一个Book类型,其中包含您的图书清单,并使用fiddle #1对其进行注释和[XmlRoot(ElementName = "book")] public class Book { [XmlElement(ElementName = "author")] public string Author { get; set; } [XmlElement(ElementName = "title")] public string Title { get; set; } [XmlElement(ElementName = "genre")] public Genre Genre { get; set; } [XmlElement(ElementName = "price")] public decimal Price { get; set; } [XmlElement(ElementName = "publish_date")] public string PublishDate { get; set; } [XmlElement(ElementName = "description")] public string Description { get; set; } [XmlAttribute(AttributeName = "id")] public string Id { get; set; } } [XmlRoot(ElementName = "catalog")] public class Catalog { [XmlElement(ElementName = "book")] public List<Book> Books { get; set; } } public enum Genre { Computer, Fantasy, }; ,并使用attributes that control XML serialization对所有内容进行反序列化。

像这样定义你的类型:

List<Book> dupa;
using (var reader = XmlReader.Create(filePath))
{
    var serializer = new XmlSerializer(typeof(Catalog));
    dupa = ((Catalog)serializer.Deserialize(reader)).Books;
}

然后按如下方式反序列化:

Genre

示例XmlSerializer

注意:

  • 考虑将enumstring更改为XmlSerializer。对于当前模型,如果稍后将新类型添加到XML,则反序列化将失败。

  • 有许多工具可以从XML自动生成与{{1}}兼容的类型。我使用了fiddle #2,然后根据需要修改了属性名称和类型。另一种选择是https://xmltocsharp.azurewebsites.net/。有关详情,请参阅xsd.exe