Click here to Skip to main content
14,697,175 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Basically, I'm removing the duplicated entries and summing their values to have only one of each entry.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication2
{
    class Program
    {
        //File
        const string FILE = "ccc.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILE);

            List <XElement> originalInvoices = doc.Descendants("Invoice").ToList();

            var groups = originalInvoices.GroupBy(x => (string)x.Element("Hash")).ToList();

            var finalInvoices = groups.Select(x => new {
                unit = x.Descendants("UnitPrice").Sum(z => (decimal)z),
                credit = x.Descendants("CreditAmount").Sum(z => (decimal)z),
                tax = x.Descendants("TaxPayable").Sum(z => (decimal)z),
                net = x.Descendants("NetTotal").Sum(z => (decimal)z),
                gross = x.Descendants("GrossTotal").Sum(z => (decimal)z),
                first = x.First()
            }).ToList();

            foreach (var finalInvoice in finalInvoices)
            {
                finalInvoice.first.Element("Line").SetElementValue("UnitPrice", finalInvoice.unit);
                finalInvoice.first.Element("Line").SetElementValue("CreditAmount", finalInvoice.credit);
                finalInvoice.first.Element("DocumentTotals").SetElementValue("TaxPayable", finalInvoice.tax);
                finalInvoice.first.Element("DocumentTotals").SetElementValue("NetTotal", finalInvoice.net);
                finalInvoice.first.Element("DocumentTotals").SetElementValue("GrossTotal", finalInvoice.gross);
            }

            doc.Element("SalesInvoices").ReplaceWith(new XElement("SalesInvoices", finalInvoices.Select(x => x.first)));
            Console.WriteLine(doc);
            Console.ReadKey();

        }
    }
}


The problem is that my code is exploding when it reaches the following line at the end:
`doc.Element("SalesInvoices").ReplaceWith(new XElement("SalesInvoices", finalInvoices.Select(x => x.first)));`


With the following error: `An unhandled exception of type 'System.NullReferenceException' occurred in ConsoleApplication2.exe`

I can't fix it my file is this one: [XML] <?xml version="1.0" encoding="UTF-8"?> <AuditFile xmlns="urn:OECD:StandardAudit - Pastebin.com[^]

Basically, the code should delete the Invoices repeated Hash and sum the values of UnitPrice, CreditAmount, TaxPayable, NetTotal, and GrossTotal, where UnitPrice and Credit must be the same as NetTotal.

So instead of having many Invoices with the same Hash, I will have only one Invoice with that hash that has the sum of the values above.

The code already removes the duplicated ones and sums the values but somehow I don't know how to fix the problem.

It would be great if someone helps me with the solution for this problem, and I also need to save the "edited" file, which is not happening but my main problem is getting rid of that error.

What I have tried:

//File
            const string FILE = "ccc.xml";
            static void Main(string[] args)
            {
                XDocument doc = XDocument.Load(FILE);
    
                List <XElement> originalInvoices = doc.Descendants("Invoice").ToList();
    
                var groups = originalInvoices.GroupBy(x => (string)x.Element("Hash")).ToList();
    
                var finalInvoices = groups.Select(x => new {
                    unit = x.Descendants("UnitPrice").Sum(z => (decimal)z),
                    credit = x.Descendants("CreditAmount").Sum(z => (decimal)z),
                    tax = x.Descendants("TaxPayable").Sum(z => (decimal)z),
                    net = x.Descendants("NetTotal").Sum(z => (decimal)z),
                    gross = x.Descendants("GrossTotal").Sum(z => (decimal)z),
                    first = x.First()
                }).ToList();
    
                foreach (var finalInvoice in finalInvoices)
                {
                    finalInvoice.first.Element("Line").SetElementValue("UnitPrice", finalInvoice.unit);
                    finalInvoice.first.Element("Line").SetElementValue("CreditAmount", finalInvoice.credit);
                    finalInvoice.first.Element("DocumentTotals").SetElementValue("TaxPayable", finalInvoice.tax);
                    finalInvoice.first.Element("DocumentTotals").SetElementValue("NetTotal", finalInvoice.net);
                    finalInvoice.first.Element("DocumentTotals").SetElementValue("GrossTotal", finalInvoice.gross);
                }
    
                doc.Element("SalesInvoices").ReplaceWith(new XElement("SalesInvoices", finalInvoices.Select(x => x.first)));
                Console.WriteLine(doc);
                Console.ReadKey();
    
            }
        }
    }
Posted
Updated 25-Mar-18 7:08am
v2

Learn how to use the Visual Studio debugger. I CANNOT stress this enough.

Put a try/catch block around your code and put a breakpoint on one of the catch block curly brackets so the debugger will stop when an exception is throw. Believe it or not, it will TELL YOU exactly which line the problem is in, and you can inspect the various objects used in that to find he null one.

static Main(string[] args)
{
    try
    {
        // all of your code
    }
    catch (Exception ex)
    { // put a breakpoint here
    } // or here
}


As a new developer, you're going to spend more time debugging your code than you will actually writing your code. Developing decent debugging skills is ESSENTIAL.
   
Your xml file contains a Namespace[^]. So, to be able to get data from your file, you have to use the name of namespace together with node/element name. See:
string sFile = @"FullFileName.xml";
XDocument xDoc = XDocument.Load(sFile);
XNamespace n = xDoc.Root.Name.Namespace;
var result = xDoc.Descendants(n+"Invoice")
    .GroupBy(x=> x.Element(n+"Hash").Value)
    .ToList();


This should help you to avoid `An unhandled exception of type 'System.NullReferenceException' error.

Good luck!
   

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900