Why am I getting first node again on second iteration in this XDocument

0

I read about XML XDocument and running a few test but now I get the same first node on second lap in the foreach

Here´s my C# code for the CRUD get:

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

Here´s the xml databas

<?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>

Also the program crash at second lap when doing 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()
c#
asp.net
xml
xdoc
asked on Stack Overflow Jun 16, 2019 by Tord Larsen • edited Jun 16, 2019 by Llama

1 Answer

1

Descendants will get both the parent and all the child nodes of each element so you will get each element multiple times like book with child Author and then get Author a second time. See code below for solution :

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; }
    }
}
answered on Stack Overflow Jun 16, 2019 by jdweng

User contributions licensed under CC BY-SA 3.0