简体   繁体   中英

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

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... ?

The issue:

When I attempt to increment the XAttribute like so:

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

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.

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 .

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.

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:

<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.

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.

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

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

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


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

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

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

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

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM