我的代码是删除重复的发票并将一些值加到主发票上,以便只保留一张具有相同哈希值的发票而不是更多相同的发票。
我的代码:
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();
}
}
}
问题是我的代码在最后到达下一行时会爆炸:
doc.Element("SalesInvoices").ReplaceWith(new XElement("SalesInvoices", finalInvoices.Select(x => x.first)));
错误:&#39; System.NullReferenceException&#39;但我不知道为什么它有空,因为我有发票,但是当我添加断点时,它没有找到任何重复的发票。
我无法解决此问题,我的文件就是这个:Pastebin XML File
基本上,代码应删除Invoices重复Hash并将UnitPrice,CreditAmount,TaxPayable,NetTotal和GrossTotal的值相加,其中UnitPrice和Credit必须与NetTotal相同。
因此,我没有多张具有相同哈希值的发票,而是只有一张具有上述值总和的哈希值。
代码已删除重复的代码并对值进行求和,但不知怎的,我不知道如何解决问题。
如果有人帮我解决问题,如何解析我的整个文件会很好,因为此刻它告诉我,当我拥有它们时我没有发票。
通过添加&#34; XNamespace n = doc.Root.Name.Namespace更新我的代码;&#34;:
XDocument doc = XDocument.Load(FILENAME);
XNamespace n = doc.Root.Name.Namespace;
List <XElement> originalInvoices = doc.Root.Descendants(n + "Invoice").ToList();
var groups = originalInvoices.GroupBy(x => (string)x.Element(n + "Hash")).ToList();
var finalInvoices = groups.Select(x => new {
unit = x.Descendants(n + "UnitPrice").Sum(z => (decimal)z),
credit = x.Descendants(n + "CreditAmount").Sum(z => (decimal)z),
tax = x.Descendants(n + "TaxPayable").Sum(z => (decimal)z),
net = x.Descendants(n + "NetTotal").Sum(z => (decimal)z),
gross = x.Descendants(n + "GrossTotal").Sum(z => (decimal)z),
first = x.First()
}).ToList();
foreach (var finalInvoice in finalInvoices)
{
finalInvoice.first.Element(n + "Line").SetElementValue("UnitPrice", finalInvoice.unit);
finalInvoice.first.Element(n + "Line").SetElementValue("CreditAmount", finalInvoice.credit);
finalInvoice.first.Element(n + "DocumentTotals").SetElementValue("TaxPayable", finalInvoice.tax);
finalInvoice.first.Element(n + "DocumentTotals").SetElementValue("NetTotal", finalInvoice.net);
finalInvoice.first.Element(n + "DocumentTotals").SetElementValue("GrossTotal", finalInvoice.gross);
}
我仍然有相同的错误,但现在当我到达foreach时,值不为null,但在行doc.Element("SalesInvoices").ReplaceWith(new XElement("SalesInvoices", finalInvoices.Select(x => x.first)));
答案 0 :(得分:0)
替换
行doc.Element("SalesInvoices").ReplaceWith(new XElement("SalesInvoices", finalInvoices.Select(x => x.first)));
通过
var firstOnes = finalInvoices.Select(x => x.first);
var xElement = new XElement("SalesInvoices", firstOnes);
var salInv = doc.Element("SalesInvoices");
salInv.ReplaceWith(xElement);
并在第一个语句上设置断点。然后单步执行并了解正在发生的事情。或者只是运行,看看在哪里得到null。
顺便说一句:如果我没有完全弄错,“群组”是IGrouping&lt;字符串,XElement&gt;,所以如果你 - 在得到“groups”之后的下一行 - 从这个列表中选择一个x,它又是一个没有后代的IGrouping。对于后者,它必须是一个XElement,对吧?
答案 1 :(得分:0)
The is two issues with your code 1) Namespaces are needed 2) SalaesInvoices is not an element of doc but a descendant
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 = @"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILE);
XElement AuditFile = doc.Root;
XNamespace ns = AuditFile.GetDefaultNamespace();
List<XElement> originalInvoices = doc.Descendants(ns + "Invoice").ToList();
var groups = originalInvoices.GroupBy(x => (string)x.Element(ns + "Hash")).ToList();
var finalInvoices = groups.Select(x => new
{
unit = x.Descendants(ns + "UnitPrice").Sum(z => (decimal)z),
credit = x.Descendants(ns + "CreditAmount").Sum(z => (decimal)z),
tax = x.Descendants(ns + "TaxPayable").Sum(z => (decimal)z),
net = x.Descendants(ns + "NetTotal").Sum(z => (decimal)z),
gross = x.Descendants(ns + "GrossTotal").Sum(z => (decimal)z),
first = x.First()
}).ToList();
foreach (var finalInvoice in finalInvoices)
{
finalInvoice.first.Element(ns + "Line").SetElementValue(ns + "UnitPrice", finalInvoice.unit);
finalInvoice.first.Element(ns + "Line").SetElementValue(ns + "CreditAmount", finalInvoice.credit);
finalInvoice.first.Element(ns + "DocumentTotals").SetElementValue(ns + "TaxPayable", finalInvoice.tax);
finalInvoice.first.Element(ns + "DocumentTotals").SetElementValue(ns +"NetTotal", finalInvoice.net);
finalInvoice.first.Element(ns + "DocumentTotals").SetElementValue(ns + "GrossTotal", finalInvoice.gross);
}
doc.Descendants(ns + "SalesInvoices").FirstOrDefault().ReplaceWith(new XElement("SalesInvoices", finalInvoices.Select(x => x.first)));
Console.WriteLine(doc);
Console.ReadKey();
}
}
}