C# (XAttribute) 中 XML 属性的一个 increment/update 整数值如何实现?

How does one increment/update integer value of an XML Attribute in C# (XAttribute)?

TL;DR:如果我在 XElement 中有一个 NumFruitsXAttribute,我怎么能 increment/update从 0 到 1,2,3... 的值?

问题:

当我尝试像这样增加 XAttribute 时:

basket.Attribute("numFruits").Value += 1 

numFruits 的结果将是 numFruits = 01(因为 0 是初始值),而预期结果应该是 numFruits = 1

不需要在解析结束时添加的全局变量,因为可能有很多篮子。

解释:

在 C# Linq to XML 中,可以像这样将 XAttributes 添加到 XElement

XElement basket = new XElement("Marys_Basket", new XAttribute("NumFruits", 0);

在示例中,我们使用 NumFruits XAttribute 作为计数器来跟踪 XDocument 中的水果数量。

当我遍历(例如)Fruit 对象列表时,每个对象也有一个 basket_owner 属性,我通过创建或添加手动将所有这些对象序列化为 XML到 XElements,在此示例中将是所有者。

由于水果列表不固定,我必须将 Fruit 元素添加到 XElement 并通过首先检查所有者元素是否存在来更新 XAttribute(我已使用 LINQ 查询完成此操作并检查如果它们为空),然后将 Fruit XElement 作为子元素添加,产生类似这样的结果:

<Root>
  <Marys_basket numFruits=2>
     <Fruit name="Mango"/>
     <Fruit name="Papaya"/>
  </Marys_basket>
  <Jons_basket numFruits=0 />
  <Bobs_basket numFruits=1> 
     <Fruit name="Apple"/>
  </Bobs_basket>
</Root>

这是一个 related question on how to increment an XML Element (in this case XElement), but not an XAttribute. And this as well 但不是专门用于增加值。

我找到了一种方法(作为答案发布),并且想探索一种更强大的方法来做到这一点。因为我的程序多次执行此操作。

到目前为止我找到的最短的方法:

basket.FirstAttribute.SetValue( Int32.Parse( basket.FirstAttribute.Value ) + 1);

注意也可以使用basket.Attribute("numFruits")

所做的是获取我们想要的属性并通过首先将现有值解析为 Integer 来设置值,然后将值递增 1。这是因为设置为 XAttributes 的值是 saved/retrieved 作为字符串。

尝试递增时 basket.Attribute("numFruits") += 1 产生 01 而不是 1 或 11 而不是 2 的原因是属性值存储为字符串,并且执行 += 操作成为字符串连接对象。

如果将 XAttribute 直接转换为 int 会更短:

basket.FirstAttribute.SetValue((int)basket.FirstAttribute + 1);

就像XElement一样,XAttribute也有一些explicit conversion operators预定义。


Working example * :

using System;
using System.Xml.Linq;
using System.Xml;

public class Program
{
    public static void Main()
    {
        var xml = @"<Root>
  <Marys_basket numFruits=""2"">
     <Fruit name=""Mango""/>
     <Fruit name=""Papaya""/>
  </Marys_basket>
  <Jons_basket numFruits=""0"" />
  <Bobs_basket numFruits=""1""> 
     <Fruit name=""Apple""/>
  </Bobs_basket>
</Root>";
        var doc = XDocument.Parse(xml);
        XElement basket = doc.Root.Element("Marys_basket");
        basket.FirstAttribute.SetValue((int)basket.FirstAttribute + 1);
        Console.WriteLine(doc.ToString());
    }
}

*: 主要是为了未来的访客,因为我相信 OP 已经知道了其余的