Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/288.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# XML数据文件未打开且工作不正常_C#_Wpf_Xml - Fatal编程技术网

C# XML数据文件未打开且工作不正常

C# XML数据文件未打开且工作不正常,c#,wpf,xml,C#,Wpf,Xml,我使用XML作为数据库文件开发了一个WPF应用程序。昨天,程序停止工作。经过一些检查,我发现Transaction.xml文件存在问题。我尝试在IE中打开相同的,但出现了此错误 无法显示XML页面 无法使用样式表查看XML输入。请更正错误,然后单击“刷新”按钮,或稍后重试 在文本内容中发现无效字符。处理资源“”时出错file:///C:/RegisterMaintenance/Transaction.xml 然后,我试着用记事本打开文件,它显示了一个奇怪的字符(下面的屏幕截图) 最后,它展示

我使用XML作为数据库文件开发了一个WPF应用程序。昨天,程序停止工作。经过一些检查,我发现Transaction.xml文件存在问题。我尝试在IE中打开相同的,但出现了此错误

无法显示XML页面

无法使用样式表查看XML输入。请更正错误,然后单击“刷新”按钮,或稍后重试


在文本内容中发现无效字符。处理资源“”时出错file:///C:/RegisterMaintenance/Transaction.xml

然后,我试着用记事本打开文件,它显示了一个奇怪的字符(下面的屏幕截图)

最后,它展示了正确的xml结构。请告诉我哪里出了问题,以及为什么xml不能正确显示。怎样才能使它恢复正常状态。我真的很担心,因为这是我唯一的数据文件。任何帮助或建议都会很好

作为编辑此文件的代码之一,还有其他类似类型的代码文件使用Transaction.xml

public string Add()
    {
        XDocument doc1 = XDocument.Load(@"Ledgers.xml");
        XElement elem = (from r in doc1.Descendants("Ledger")
                where r.Element("Name").Value == this.Buyer
                select r).First();
        this.TinNo = (string)elem.Element("TinNo");
        this.PhoneNo = (string)elem.Element("PhoneNo");
        this.CommissionAmount = (this.CommissionRate * this.Amount) / 100;
        this.CommissionAmount = Math.Round((decimal)this.CommissionAmount);
        this.VatAmount = (this.CommissionAmount + this.Amount) * this.VatRate / 100;
        this.VatAmount = Math.Round((decimal)this.VatAmount);
        this.InvoiceAmount = this.Amount + this.CommissionAmount + this.VatAmount;
        XDocument doc2 = XDocument.Load(@"Transactions.xml");
        var record = from r in doc2.Descendants("Transaction")
                     where (int)r.Element("Serial") == Serial
                     select r;
        foreach (XElement r in record)
        {
            r.Element("Invoice").Add(new XElement("InvoiceNo", this.InvoiceNo), new XElement("InvoiceDate", this.InvoiceDate),
                new XElement("TinNo", this.TinNo), new XElement("PhoneNo", this.PhoneNo), new XElement("TruckNo", this.TruckNo), new XElement("Source", this.Source),
                new XElement("Destination", this.Destination), new XElement("InvoiceAmount", this.InvoiceAmount),
                new XElement("CommissionRate", this.CommissionRate), new XElement("CommissionAmount", this.CommissionAmount),
                new XElement("VatRate", this.VatRate), new XElement("VatAmount", this.VatAmount));
        }
        doc2.Save(@"Transactions.xml");
        return "Invoice Created Successfully";
    }

.xml的格式显然不正确。任何浏览器或其他读取xml文件的程序都无法对其执行任何操作。在某些行之后,xml是否开始正确并不重要

因此,无论创建和/或编辑xml文件的内容是什么,错误都是显而易见的。你应该看看那里。也许编码是错误的。最常用的编码是UTF-8

另外,作为补充说明,XML并不是大型数据库的最佳格式(开销太大),因此最好切换到二进制格式。即使切换到JSON也会带来好处。

C#是一种面向对象编程(OOP)语言,也许您应该使用一些对象!如何测试代码的准确性

您应该将责任分开,例如:

public class Vat
{
    XElement self;
    public Vat(XElement parent)
    {
        self = parent.Element("Vat");
        if (null == self)
        {
            parent.Add(self = new XElement("Vat"));
            // Initialize values
            Amount = 0; 
            Rate = 0;
        }
    }

    public XElement Element { get { return self; } }

    public decimal Amount
    {
        get { return (decimal)self.Attribute("Amount"); }
        set
        {
            XAttribute a = self.Attribute("Amount");
            if (null == a)
                self.Add(new XAttribute("Amount", value));
            else
                a.Value = value.ToString();
        }
    }

    public decimal Rate
    {
        get { return (decimal)self.Attribute("Rate"); }
        set
        {
            XAttribute a = self.Attribute("Rate");
            if (null == a)
                self.Add(new XAttribute("Rate", value));
            else
                a.Value = value.ToString();
        }
    }
}
所有Vat数据都将在一个节点中,对它的所有访问都将在一个可测试类中

您上面的foreach看起来更像:

foreach(XElement r in record)
{
    XElement invoice = r.Add("Invoice");
    ...
    Vat vat = new Vat(invoice);
    vat.Amount = this.VatAmount;
    vat.Rate = this.VatRate;
}
那是可读的!乍一看,从您的代码中,我甚至无法判断发票是否是增值税的父项,但我现在可以

注意:这并不是说您的代码有错,可能是硬盘驱动器错误,因为在我看来就是这样。但是,如果您希望人们阅读您的代码,请使其可读性和可测试性!几年后,如果您或其他人必须更改您的代码,如果代码不可读,那么它将毫无用处

也许从这次事件中你学到了两件事

  • 阅读能力和测试能力
  • 备份!(我所有有价值的Xml文件都在SVN(TortoiseSVN)中,因此我可以比较更改的内容,并保留良好的备份。SVN将备份到在线存储。)
  • 理想的下一步是将属性设置器中的代码重构为可测试和可复制的静态函数扩展:

    public static class XAttributeExtensions
    {
        public static XAttribute SetAttribute(this XElement self, string name, object value)
        {
            // test for correct arguments
            if (null == self)
                throw new ArgumentNullException("XElement to SetAttribute method cannot be null!");
            if (string.IsNullOrEmpty(name))
                throw new ArgumentNullException("Attribute name cannot be null or empty to SetAttribute method!");
            if (null == value) // how to handle?
                value = ""; // or can throw an exception like one of the above.
    
            // Now to the good stuff
            XAttribute a = self.Attribute(name);
            if (null == a)
                self.Add(a = new XAttribute(name, value));
            else
                a.Value = value.ToString();
            return a;
        }
    }
    
    这是很容易测试,非常可读,最好的是它可以反复使用得到相同的结果

    例如,“金额”属性可以通过以下方式大大简化:

    public decimal Amount
    {
        get { return (decimal)self.Attribute("Amount"); }
        set { self.SetAttribute("Amount", value); }
    }
    

    我知道这是很多锅炉板代码,但我发现它可读、可扩展,而且最好是可测试的。如果我想给Vat添加另一个值,我可以修改这个类,而不必担心是否在正确的位置添加了它。如果Vat有孩子,我会创建另一个Vat有属性的类。

    它是
    是否有任何编辑器打开此文件以避免出现奇怪的字符(可能是UltraEdit)?@Ivan_u83我下载了UltraEdit并用它打开了文件。其显示方式相同:-(假设您的数据通常不是一堆设备和软件包名称是否安全?如果这与您的应用程序无关,并且本地驱动器出现问题,我不会感到惊讶。运行chkdsk。这是
    。现在可以做什么?我可以将其恢复到正常状态吗?不,我不是指xml文件的备份(顺便说一句,这是非常可选的)。我的意思是,首先编写或编辑xml的程序可能会产生这种混乱的xml开头。I文件由我开发的WPF应用程序读取和编写。后端语言是c#,那么最好在负责xml编写的应用程序中显示代码。如果太大,则不显示所有代码;)我已使用编辑此文件的其中一个代码编辑了问题。还有其他文件也可以读取和编辑此文件。我已显示其中一个代码