1

I have XML like

<?xml version="1.0" ?> 
<Hospital>
  <DR>
    <Salary>1000</Salary>
    <bonus> 3 </bonus>
  </DR>
  <Nurse>
    <Shift> </Shift>
  </Nurse>
</Hospital> 

I want to search for either Nurse or Dr, and update certain inner element's value (the update affect the XML file) in it using index (0,1,2,3). I can get the inner elements name too, for example I want to update salary inner node.

How to do that using XML and LINQ , put in consideration that the inner elements are different in number and name ?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
AMH
  • 6,363
  • 27
  • 84
  • 135
  • Are you sure you want to update a Doctor's salary based on the index of a node in an XML file :-) ? Don't you have attributes for name for example : ? In which case you can use XPATH queries to select elements more precisely. – Anas Karkoukli Oct 26 '11 at 14:12
  • Yes I'm sure from that . I have only node without attribute – AMH Oct 26 '11 at 14:18
  • You say also there might be many DR or Nurse elements inside XML, how are you going to distinguish one doctor from another, by name? Or just be index? Example, if you have 3 DR elements, you want the second to be updated? – Anas Karkoukli Oct 26 '11 at 14:38

1 Answers1

2

Based on your reply to my comment and your certainty in the question that you want to select nodes by index, here is a simple way to acheive it. Assuming your XML have multiple DR (with no names or other means to identify them). I use XPATH here because in your case it might be easier than LINQ.

Assuming the XML is:

<Hospital> 
    <DR> 
        <Salary>1000</Salary> 
        <bonus> 3 </bonus> 
    </DR> 
    <DR> 
        <Salary>2000</Salary> 
        <bonus> 7 </bonus>  
    </DR> 
    <Nurse> 
        <Shift> </Shift> 
    </Nurse> 
</Hospital>

You can select the second node using an XPATH instead as follows:

XmlDocument xmlDocument = new XmlDocument();
xmlDocument.LoadXml(xmlString);
XPathNavigator navigator = xmlDocument.CreateNavigator();

XPathNavigator node = navigator.SelectSingleNode("/Hospital/DR[2]/Salary");
if (node != null)
    node.SetValue("new salary");

Please note the Xpath index [] is 1 based not 0 based. So DR[2] selects the second node.

EDIT:

And in answer to your second question, if you have a name attribute in the DR element. You can get and update that value much like the preceding example, all you need to change is the Xpath to point to that attribute, as such:

/Hospital/DR[2]/@name
Anas Karkoukli
  • 1,342
  • 8
  • 13
  • it not save in the file, I tried XmlTextWriter writer = new XmlTextWriter(ViewerManager.Dir_Temp + "\\" + ViewerManager.UserProfile_FileName + @"\\" + "Shortcuts.xml", null); writer.Formatting = Formatting.Indented; writer.Indentation = 3; doc.WriteTo(writer); ViewerManager.SaveProfile = true; writer.Close();, but it result in corrupted file – AMH Oct 27 '11 at 08:36
  • Of course it will not save it, `node.SetValue` updates the xml in memory, in order to save to a file, use the `XmlDocument.Save()` method. You can either save the modified XML to a file or to a stream. Read this documentation to cover all the possibilities: http://msdn.microsoft.com/en-us/library/dw229a22.aspx – Anas Karkoukli Oct 27 '11 at 23:36