当写入文件3行被删除时,不应该删除

时间:2018-04-10 18:38:38

标签: c# xml linq

我正在删除一个XML文件中的重复条目,代码正在删除它们并将值相加以使每个发票只有一个条目。 但当它到达终点时,它会删除3行:

      <NumberOfEntries>11972</NumberOfEntries>
      <TotalDebit>0</TotalDebit>
      <TotalCredit>34422.86</TotalCredit>

所以不要像最终文件那样:

...
      <SourceDocuments>
        <SalesInvoices>
          <NumberOfEntries>11972</NumberOfEntries>
          <TotalDebit>0</TotalDebit>
          <TotalCredit>34422.86</TotalCredit>
          <Invoice>
            <InvoiceNo>FS 006120180101/19959</InvoiceNo>
...

看起来像是:

...
      <SourceDocuments>
        <SalesInvoices>
          <Invoice>
            <InvoiceNo>FS 006120180101/19959</InvoiceNo>
...

我的代码如下:

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

namespace ConsoleApplication2
{
    class Program
    {

        //Ficheiro 
        const string FILENAME = "ccc.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILENAME);

            XNamespace ns = doc.Root.Name.Namespace;



            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(ns + "SalesInvoices", finalInvoices.Select(x => x.first)));
            doc.Descendants(ns + "SalesInvoices").
            Console.WriteLine(doc);
            doc.Save("Root.xml");
            Console.ReadKey();

        }
    }
    }

您可以在此处查看我的XML文件示例:Pastebin Link

有人可以帮我解决这个问题,如何才能删除这3行? 问题可能出在写文件的最后一行,但我不确定。

doc.Descendants(ns + "SalesInvoices").FirstOrDefault().ReplaceWith(new XElement(ns + "SalesInvoices", finalInvoices.Select(x => x.first)));

问题的小更新: 好吧,我真的认为问题出在上面,因为如果我改为SalesInvoices TotalCredit... <SourceDocuments> <SalesInvoices> <Invoice> <InvoiceNo>FS 006120180101/19959</InvoiceNo> ... 是最后一行正在消失的文件仍然是错误的,而不是:

...
      <SourceDocuments>
        <SalesInvoices>
          <NumberOfEntries>11972</NumberOfEntries>
          <TotalDebit>0</TotalDebit>
          <TotalCredit>
          <Invoice>
            <InvoiceNo>FS 006120180101/19959</InvoiceNo>
...

我得到了:

34422.86</TotalCredit>

标记<Invoice>

之前缺少</TotalCredit>

并且在第一个已关闭的元素</Invoice>之后添加private lazy var foo: Void = { objc_sync_enter(self) defer { objc_sync_exit(self) } // Do this once }() ,因为您可以在此处测试:Link to test the code

1 个答案:

答案 0 :(得分:0)

易于修复。只需添加缺少的3个元素:

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

            XElement salesInvoices = doc.Descendants(ns + "SalesInvoices").FirstOrDefault();
            XElement numberOfEntries = salesInvoices.Element(ns + "NumberOfEntries");
            XElement totalDebit = salesInvoices.Element(ns + "TotalDebit");
            XElement totalCredit = salesInvoices.Element(ns + "TotalCredit");

            salesInvoices.ReplaceWith(new XElement(ns + "SalesInvoices", new object[] {
                numberOfEntries,
                totalDebit,
                totalCredit,
                finalInvoices.Select(x => x.first)
            }));