如何在linq中编辑xml中的特定项

本文关键字:xml 编辑 linq | 更新日期: 2023-09-27 18:11:18

我必须创建一个xml文档,并通过LINQ对xml概念执行以下项目。

  1. 添加新资源,
  2. 编辑资产,
  3. 删除资产。

我用记事本创建了一个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开始。

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

系统。NULL引用异常

谁能告诉我在这个程序中我做错了什么,并建议我简单的方法来纠正这个问题。基本上,我不是来自IT领域,我是一名电气工程师,所以请稍微深入地解释一下。

如何在linq中编辑xml中的特定项

嗯,我看到你的代码中有几件事要做

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

空引用异常

这个异常意味着,你正在尝试使用一些变量,但这个变量是空的,所以它没有任何值。从第一次看你的代码,我可以看到,在一些地方,你试图加载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结构更改为我建议的结构,然后使用这个答案中的片段重写我指出的这些行,然后您应该就可以了!