如何在linq中编辑特定项目到xml

时间:2016-10-03 06:51:46

标签: c# xml linq

我必须创建一个xml文档,并按照LINQ to XML概念执行以下项目。

  1. 添加新资产
  2. 编辑资产,
  3. 删除资产。
  4. 我正在通过记事本创建一个xml文档并通过“asset.xml”保存该文件然后将该文件复制到调试文件夹

    我的xml文档格式是

    <?xml version="1.0" encoding="utf-8"?>
    <Assets>
      <assetId>1
           <assetName>lenova</assetName>
           <model>12kj320</model>
           <price>22000</price>
           <quantity>12</quantity>
       </assetId>
    </Assets>
    

    我的代码是

    class program
    {
    
    public static void AddSingleAsset()
    {
        static List<Asset> Assets = new List<Asset>();
    
        int assetId;
        string assetName;
        string model;
        double price;
        int quantity;
        assetId = Assets.Count + 1;
        Console.WriteLine("Asset id :{0}", assetId);
        Console.WriteLine("Enter the asset name");
        assetName = Console.ReadLine();
        Console.WriteLine("Enter the asset model");
        model = Console.ReadLine();
        Console.WriteLine("Enter the price of asset");
        price = int.Parse(Console.ReadLine());
        Console.WriteLine("Enter the quantity of asset");
        quantity = int.Parse(Console.ReadLine());
        Assets.Add(new Asset() { assetId = assetId, assetName = assetName, modelNo = model, price = price, quantity = quantity });
        string path = "linqtoxml1.xml";
        XDocument doc = XDocument.Load(path);
        doc.Elements("Assets").First().AddFirst(new XElement("assetId", assetId, new XElement("assetName", assetName), new XElement("model", model), new XElement("price", price), new XElement("quantity", quantity)));
        doc.Save(path);
    
    }
    public static void EditAssetInformation()
    {
        Console.WriteLine("select the option to edit");
        Console.WriteLine("1.To change Asset Name\n2.To change Model NO\n3.To change price\n4.To change Quantity");
        int option = int.Parse(Console.ReadLine());
        switch (option)
        {
            case 1:
                string newname;
                Console.WriteLine("Enter the ID number to change the information");
                int id = int.Parse(Console.ReadLine());
                Console.WriteLine("Enter the Asset new name");
                newname = Console.ReadLine();
                ModifyName(newname, id);    
                break;
    
            case 2:
                string newModelNo;
                Console.WriteLine("Enter the ID number to change the information");
                int id1 = int.Parse(Console.ReadLine());
                Console.WriteLine("Enter the Asset new model No");
                newModelNo = Console.ReadLine();
                ModifyModelNo(newModelNo, id1);
                break;
    
            case 3:
                double newPrice;
                Console.WriteLine("Enter the ID number to change the information");
                int id2 = int.Parse(Console.ReadLine());
                Console.WriteLine("Enter the Asset new price");
                newPrice = int.Parse(Console.ReadLine());
                ModifyPrice(newPrice, id2);
                break;
    
            case 4:
                int newQuantity;
                Console.WriteLine("Enter the ID number to change the information");
                int id3 = int.Parse(Console.ReadLine());
                Console.WriteLine("Enter the Asset new price");
                newQuantity = int.Parse(Console.ReadLine());
                Modifyquantity(newQuantity, id3);
                break;
    
            }
        }
        static void ModifyName(string newname, int id)
        {
            var doc = XElement.Load(path);
            var namechange = doc.Element("Assets").Elements("assetId").Where(c => c.Element("assetId").Value == Convert.ToString(id)).Single();
            namechange.Element("assetName").Value = newname;
            doc.Save(path);
        }
        static void ModifyModelNo(string newModelNo, int id1)
        {
            string path = "linqtoxml1.xml";
            XDocument doc = XDocument.Load(path);
            XElement modelchange = doc.Descendants("AssetId").Where(c => c.Attribute("AssetId").Value.Equals(id1.ToString())).FirstOrDefault();
            modelchange.Element("model").Value = newModelNo;
            doc.Save(path);
        }
        static void ModifyPrice(double newPrice, int id2)
        {
            string path = "linqtoxml1.xml";
            XDocument doc = XDocument.Load(path);
            XElement pricechange = doc.Descendants("AssetId").Where(c => c.Attribute("AssetId").Value.Equals(id2.ToString())).FirstOrDefault();
            pricechange.Element("price").Value = newPrice.ToString();
            doc.Save(path);
        }
        static void Modifyquantity(int newQuantity, int id3)
        {
            string path = "linqtoxml1.xml";
            XDocument doc = XDocument.Load(path);
            XElement quantitychange = doc.Descendants("AssetId").Where(c => c.Attribute("AssetId").Value.Equals(id3.ToString())).FirstOrDefault();
            quantitychange.Element("quantity").Value = newQuantity.ToString();
            doc.Save(path);
        }
        public static void DeleteAssetInformation()
        {
            string path = "linqtoxml1.xml";
            Console.WriteLine("Enter the ID to delete information");
            int id = int.Parse(Console.ReadLine());
            XDocument doc = XDocument.Load(path);
            XElement cStudent = doc.Descendants("AssetId").Where(c => c.Attribute("ID").Value.Equals(id.ToString())).FirstOrDefault();
            cStudent.Remove();
            doc.Save(path);
        }
    }
    public class Asset
    {
        public int assetId
        { get; set; }
        public string assetName
        { get; set; }
        public string modelNo
        { get; set; }
        public double price
        { get; set; }
        public int quantity
        { get; set; }
    }
    

    我的问题是

    我需要自动生成资产ID。当我关闭此控制台并再次运行时,我连续添加元素时,我的代码才有效,然后资产ID将从1再次开始。

    当我尝试编辑或删除之前的记录意味着将显示错误:

      

    SYSTEM.NULL REFERENCE EXCEPTION

    任何人都可以解释一下我在这个程序中做错了什么,并建议我简单的方法来纠正这个问题。基本上我来自非IT领域,我是一名电气工程师,所以请稍微解释一下。

1 个答案:

答案 0 :(得分:0)

好吧,我发现你的代码还有几件事情

XML文件

你的xml看起来像这样

<?xml version="1.0" encoding="utf-8"?>
<Assets>
  <assetId>1
       <assetName>lenova</assetName>
       <model>12kj320</model>
       <price>22000</price>
       <quantity>12</quantity>
   </assetId>
</Assets>

节点无效 - 您应该在值之后立即结束此节点。 <assetId>节点有效,但更好一点,更改此结构。如果你有一个名为<Assets>的节点,最好将每个资产封装在他自己的节点中,称为<asset>

<?xml version="1.0" encoding="utf-8"?>
<Assets>
   <asset>
      <assetId>1</assetId>
      <assetName>lenova</assetName>
      <model>12kj320</model>
      <price>22000</price>
      <quantity>12</quantity>
   </asset>
</Assets>

完成此更改后,您将能够通过简单的

找到所有资产
var assets = root.Elements("asset");

如果您想添加新资源并获取正确的新ID值,您可以执行类似这样的操作

var assets = root.Elements("asset").OrderByDescending(asset => asset.Element("assetId").Value);

现在,id值最高的资产位于顶部,因此,要计算新ID,您应该执行类似

的操作
var newestAsset = root.Elements("asset").OrderByDescending(asset => asset.Element("assetId").Value).FirstOrDefault();
int newId = int.Parse(newestAsset.Element("assetId").Value) + 1;

因此,添加新资产将如下所示

XElement root = XElement.Load(path);
XElement newAsset = new XElement("asset", new XElement("assetId", newId)/*, other asset properties */);
root.Add(newAsset);
root.Save(path);

空引用异常

此异常意味着您尝试使用某个变量,但此变量为null,因此它没有任何值。从第一次看你的代码我可以看到,在某些地方,你试图使用路径变量加载xml元素,但它没有初始化。例如,在ModifyName方法中。

其他可能性是,此行存在问题

var namechange = doc.Element("Assets").Elements("assetId").Where(c => c.Element("assetId").Value == Convert.ToString(1)).Single();

和这一个

XElement modelchange = doc.Descendants("AssetId").Where(c => c.Attribute("AssetId").Value.Equals(1.ToString())).FirstOrDefault();

我想,在这两行的某个地方,某些东西是空的,但你试图以这种方式处理这个元素。在这种情况下,您应该使用调试器并查看此异常的来源。有了这些信息,您就会知道,为了使这个程序有效,您应该更改哪些行。

如果您想在控制台窗口中找到用户提供的id资产,代码应如下所示

var asset = root.Elements("asset").Where(asset => asset.Element("assetId").Value == id.ToString()); 

首先,将你的xml结构更改为我建议的结构,而不是重写这些使用此答案的片段指出你的行,你应该好好去吧!