为什么在此XDocument

时间:2019-06-16 11:45:23

标签: c# asp.net xml xdoc

我了解了XML XDocument并进行了一些测试,但是现在我在foreach的第二圈得到了相同的第一个节点

这是我的CRUD的C#代码:

 public IActionResult GetBookItems()
        {
            List<BookItem> BookItems = new List<BookItem>();
            XDocument doc = _db.GetXmlDb();
            foreach (XElement element in doc.Root.Descendants())
            {
                BookItem bookitem = new BookItem
                {
                    /// Id 
                    /// Author
                    /// Title
                    /// Genre
                    /// Price
                    /// Publish_date
                    /// Description
                    Id = element.Attribute("id").Value,
                    Author = element.Element("author").Value,
                    Title = element.Element("title").Value,
                    Genre = element.Element("genre").Value,
                    Price = element.Element("price").Value,
                    Publish_date = element.Element("publish_date").Value,
                    Description = element.Element("description").Value
                };

                BookItems.Add(bookitem);
                BookItems = BookItems.OrderBy(p => p.Title).ToList();
            }

            return Ok(BookItems);
        }

这是xml数据库

<?xml version="1.0"?>
<catalog>
   <book id="B1">
      <author>Kutner, Joe</author>
      <title>Deploying with JRuby</title>
      <genre>Computer</genre>
      <price>33.00</price>
      <publish_date>2012-08-15</publish_date>
      <description>Deploying with JRuby is the missing link between enjoying JRuby and using it in the real world to build high-performance, scalable applications.</description>
   </book>
   <book id="B2">
      <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>

执行new BookItem时,程序在第二圈崩溃

System.NullReferenceException
  HResult=0x80004003
  Message=Object reference not set to an instance of an object.
  Source=BooksProject
  StackTrace:
   at WorkSampleBookSearch.BooksXmlController.GetBookItems() in L:\NetProject\BooksProject\BooksProject\Controllers\BooksXmlController.cs:line 34
   at Microsoft.Extensions.Internal.ObjectMethodExecutor.Execute(Object target, Object[] parameters)
   at Microsoft.AspNetCore.Mvc.Internal.ActionMethodExecutor.SyncActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeActionMethodAsync>d__12.MoveNext()

1 个答案:

答案 0 :(得分:1)

后代将同时获得每个元素的父节点和所有子节点,因此您将多次获得每个元素,例如与带有子Author的book一起,然后再次获得Author。请参见下面的代码以获取解决方案:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILENAME);

            List<BookItem> bookitems = doc.Descendants("book").Select(x => new BookItem() {
                Id = (string)x.Attribute("id"),
                Author = (string)x.Element("author"),
                Title = (string)x.Element("title"),
                Genre = (string)x.Element("genre"),
                Price = (decimal)x.Element("price"),
                Publish_date = (DateTime)x.Element("publish_date"),
                Description = (string)x.Element("description")
            }).ToList();

        }
    }
    public class BookItem
    {
        public string Id { get; set; }
        public string Author { get; set; }
        public string Title { get; set; }
        public string Genre { get; set; }
        public decimal Price { get; set; }
        public DateTime Publish_date { get; set; }
        public string Description { get; set; }
    }
}