编写文件时,删除了3行,不应[英] When writing file 3 lines are deleted, and should not

本文是小编为大家收集整理的关于编写文件时,删除了3行,不应的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

我正在删除一个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>

并且在第一个关闭元素</Invoice>之后添加</TotalCredit>,您可以在此处进行测试:链接以测试测试代码

推荐答案

易于修复.只需添加丢失的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)
            }));

本文地址:https://www.itbaoku.cn/post/1557189.html

问题描述

I am removing the duplicated entries in one XML file, and the code is removing them and summing the values to have only one entry of each invoice. But when it reaches the end it removes 3 lines the following ones:

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

So instead of having the final file like:

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

It appears like:

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

My code is the following one:

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

        }
    }
    }

And you can see a sample of my XML file here: Pastebin Link

Can someone help me with this, how can I make it to not remove those 3 lines? The problem is probably on the last line where it writes the file, but I'm not sure.

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

Small Update on the question: Well I really think that the problem is on the line above because if I change for example SalesInvoices with TotalCredit which is the last line of the ones that are disappearing the file still wrong but instead of:

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

I'm getting:

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

there is a missing 34422.86</TotalCredit> before tag <Invoice>

and it's adding the </TotalCredit> after the first closed element </Invoice> as you can test here: Link to test the code

推荐答案

Easy to fix. Just add the missing 3 elements :

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