如何在C#(XAttribute)中增加/更新XML属性的整数值?

时间:2022-01-15 07:20:08

TL;DR: If I have an XAttribute of NumFruits in an XElement, how can I increment/update the value from 0 to 1,2,3... ?

TL; DR:如果我在XElement中有一个NumFruits的XAttribute,我怎样才能将值从0增加/更新为1,2,3 ...?

The issue:

When I attempt to increment the XAttribute like so:

当我尝试增加XAttribute时:

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

the result for numFruits will be numFruits = 01 (since 0 was the initial value), when the intended result was supposed to be numFruits = 1

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

Global variables that are added at the end of the parsing is not desired as there can be many baskets.

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

Explanation:

In C# Linq to XML, one can add XAttributes to an XElement like so.

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

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

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

where in the example we use NumFruits XAttribute as a counter to keep track of number of fruits in the XDocument.

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

As I interate through a list of (for example) Fruit objects that each also have a basket_owner property, I serialize all those objects to XML manually by creating or adding to XElements which in this example would be the owners.

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

As the list of fruits is not fixed, I have to add Fruit elements to the XElement and update the XAttribute by first checking if the owner element exists (I've done this with LINQ queries and checking if they are null) and then adding the Fruit XElement as a child, yielding something like so:

由于水果列表没有修复,我必须将水果元素添加到XElement并通过首先检查所有者元素是否存在来更新XAttribute(我已经使用LINQ查询并检查它们是否为空)然后添加水果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>

Here's a related question on how to increment an XML Element (in this case XElement), but not an XAttribute. And this as well but not specifically to increasing a value.

这是一个关于如何增加XML元素(在本例中为XElement)但不是XAttribute的相关问题。这也是这个,但不是专门提高价值。

I've found one method (posted as an answer) and would like to explore a more robust way to do so. As my program does this multiple times.

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

2 个解决方案

#1


Would be even shorter if you cast the XAttribute to int directly :

如果直接将XAttribute强制转换为int,则会更短:

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

Just like XElement, XAttribute also has some explicit conversion operators predefined.

就像XElement一样,XAttribute也有一些预定义的显式转换运算符。


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

*: Mainly for future visitor, as I believe OP already know about the rest

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

#2


The shortest way of doing it I've found so far:

到目前为止我发现的最短的方式:

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

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

Note that basket.Attribute("numFruits") can also be used.

注意,也可以使用basket.Attribute(“numFruits”)。

What that does is grab the attribute we want and set the value by first parsing the existing value as an Integer and then increment the value by 1. This is because values set as XAttributes are saved/retrieved as strings.

这样做是抓取我们想要的属性并通过首先将现有值解析为整数来设置值,然后将值增加1.这是因为设置为XAttributes的值被保存/检索为字符串。

The reason that doing basket.Attribute("numFruits") += 1 yields 01 instead of 1 or 11 instead of 2 when attempting to increment is that Attribute values are stored as strings, and doing a += operation becomes a string concatenation object.

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

#1


Would be even shorter if you cast the XAttribute to int directly :

如果直接将XAttribute强制转换为int,则会更短:

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

Just like XElement, XAttribute also has some explicit conversion operators predefined.

就像XElement一样,XAttribute也有一些预定义的显式转换运算符。


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

*: Mainly for future visitor, as I believe OP already know about the rest

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

#2


The shortest way of doing it I've found so far:

到目前为止我发现的最短的方式:

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

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

Note that basket.Attribute("numFruits") can also be used.

注意,也可以使用basket.Attribute(“numFruits”)。

What that does is grab the attribute we want and set the value by first parsing the existing value as an Integer and then increment the value by 1. This is because values set as XAttributes are saved/retrieved as strings.

这样做是抓取我们想要的属性并通过首先将现有值解析为整数来设置值,然后将值增加1.这是因为设置为XAttributes的值被保存/检索为字符串。

The reason that doing basket.Attribute("numFruits") += 1 yields 01 instead of 1 or 11 instead of 2 when attempting to increment is that Attribute values are stored as strings, and doing a += operation becomes a string concatenation object.

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