Click here to Skip to main content
15,886,873 members
Please Sign up or sign in to vote.
1.50/5 (2 votes)
See more:
first of all, i need to finish this really fast so i dont have a time searching on google, so if there is anyone for quick help, this is it:

i have this little xml file,

XML
<?xml version="1.0" encoding="UTF-8"?>

<volumes>
  <players>
      <volume name="vol1">75</volume>
	  <volume name="vol2">50</volume>
	  <volume name="vol3">100</volume>
  </players>
</volumes>


i need programatically to change the value of these volume names, for example, i have input parameter "vol2" with new value of 70, and i need to change, 50 to 70, how can i do this? tnx in advance.

tried something like:

C#
string filepath = Settings.GetProjectDirectory() + "\\Data\\volumes.xml";
XDocument xdoc = XDocument.Load(filepath);
var element = xdoc.Elements("vol2").Single();
element.Value = Volume.ToString();
xdoc.Save(filepath);


but i get an error .. "sequence contains no elements" ..
Posted
Updated 10-Sep-15 10:08am
v4
Comments
Matt T Heffron 10-Sep-15 16:11pm    
Really?!
You think that asking here and then WAITING for someone MAYBE to give you the code you need is going to be faster than Googling for "c# xml change value of node"?
By the way, this query gives nearly HALF A MILLION hits!

And, if you're given the code, what will you learn?

With your given structure, try something like:
C#
var element = xdoc.Elements("volume").Single(v => v.Attributes("name").Any(a => a.Value == "vol2"));

This probably is not particularly efficient!!!
BTW: if there is no element with name == "vol2" the .Single will throw an exception!

[Edit: MTH]
"Borrowing" from Maciej's solution:
C#
var element = xdoc.Descendents("volume").Single(v => (string)v.Attribute("name") == "vol2");
 
Share this answer
 
v3
Comments
Maciej Los 10-Sep-15 16:36pm    
Nice, +5!
SrgjanX 10-Sep-15 16:37pm    
it returns error: sequence contains no maching element
Matt T Heffron 10-Sep-15 16:41pm    
See the changes I "borrowed" from Maciej's solution.
Particularly the "Descendents" vs. "Elements"
Matt T Heffron 10-Sep-15 16:52pm    
I just tried mine (fixing the typo in spelling of "Descendants") and it works.
Try this:
C#
var element = xdoc.Descendants("volume").Where(x=>(string)x.Attribute("name")=="vol2").FirstOrDefault();


Complete LinqPad code:
C#
string xcontent =@"<?xml version='1.0' encoding='UTF-8'?>
<volumes>
  <players>
      <volume name='vol1'>75</volume>
      <volume name='vol2'>50</volume>
      <volume name='vol3'>100</volume>
  </players>
</volumes>";

XDocument xdoc = XDocument.Parse(xcontent);

var xelement = xdoc.Descendants("volume").Where(x=>(string)x.Attribute("name")=="vol2").FirstOrDefault();

xelement.Dump();


Returns:
XML
<volume name="vol2">50</volume>
 
Share this answer
 
v3
Comments
Matt T Heffron 10-Sep-15 16:34pm    
Similar to mine, but yours still returns IEnumerable<XElement>. Not a single XElement
But your Where condition is better than my Single condition!
Maciej Los 10-Sep-15 16:36pm    
You're right, Matt. Updated!
SrgjanX 10-Sep-15 16:39pm    
it returns System.Collections.Generic.IEnumerable<system.xml.linq.xelement>' does not contain a definition for 'Value' and no extension method 'Value', i added .firstordefault at the end, then it returns, object reference not set to an instance of an object, :/// (guess not found)
SrgjanX 10-Sep-15 16:41pm    
oh wait it works :D thank you so much, now i need to review the code to see how it works, i need to learn xml. writing and reading. thank you so much
Maciej Los 10-Sep-15 16:45pm    
You're very welcome.
You are doing it wrong. Your document contains only one element, "volumes". XML allows only one root element, by the way.

It's not clear what you mean by "changing value". Where? If your need to change the value in the file itself, you have to parse the file and write it again, with the changes you need. .NET FCL offers different ways for XML parsing/generation. This is my short overview of them:
  1. Use System.Xml.XmlDocument class. It implements DOM interface; this way is the easiest and good enough if the size if the document is not too big.
    See http://msdn.microsoft.com/en-us/library/system.xml.xmldocument.aspx.
  2. Use the classes System.Xml.XmlTextWriter and System.Xml.XmlTextReader; this is the fastest way of reading, especially is you need to skip some data.
    See http://msdn.microsoft.com/en-us/library/system.xml.xmlwriter.aspx, http://msdn.microsoft.com/en-us/library/system.xml.xmlreader.aspx.
  3. Use the class System.Xml.Linq.XDocument; this is the most adequate way similar to that of XmlDocument, supporting LINQ to XML Programming.
    See http://msdn.microsoft.com/en-us/library/system.xml.xmldocument.aspx, http://msdn.microsoft.com/en-us/library/bb387063.aspx.


I'm not sure you really need to work with .NET directly. It's pretty likely that it would be better to use serialization which automatically persist some object graph in some stream in XML (or JSON) form and restores it back to memory later. Please see:
https://en.wikipedia.org/wiki/Serialization[^],
https://msdn.microsoft.com/en-us/library/ms233843.aspx[^].

The most advanced, robust, non-intrusive and easiest to use approach to serialization is Method Contract. Please see: https://msdn.microsoft.com/en-us/library/ms733127%28v=vs.110%29.aspx[^].

—SA
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900