Reputation: 91
I have the following XML file:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<masterController> <uuid>bcbd01ac-78ff-4656-997b-d4ccc72882d1</uuid>
<channels>
<channel>
<nodeGroups>
<nodeGroup>
<analogNode>
<typeCode>8</typeCode>
<id>1</id>
<sdos>
<sdo>
<description>Host ID</description>
<compareLevel>Ignore</compareLevel>
<datafield>
<description>Host ID</description>
<compareLevel>Ignore</compareLevel>
<offset>2</offset>
<size>1</size>
<readonly>true</readonly>
<isMappedToPdo>false</isMappedToPdo>
<ownerNodeSerial>12102904</ownerNodeSerial>
<ownerSdoIndex>3</ownerSdoIndex>
<data>
<value>2</value>
<unit></unit>
<min>1</min>
<max>15</max>
</data>
<intValue>2</intValue>
</datafield>
<index>3</index>
<totalbytes>3</totalbytes>
</sdo>
<sdo>
<description>Host ID</description>
<compareLevel>Ignore</compareLevel>
<datafield>
<description>Host ID</description>
<compareLevel>Ignore</compareLevel>
<offset>2</offset>
<size>1</size>
<readonly>true</readonly>
<isMappedToPdo>false</isMappedToPdo>
<ownerNodeSerial>12102905</ownerNodeSerial>
<ownerSdoIndex>4</ownerSdoIndex>
<data>
<value>16</value>
<unit></unit>
<min>1</min>
<max>15</max>
</data>
<intValue>2</intValue>
</datafield>
<index>3</index>
<totalbytes>3</totalbytes>
</sdo>
</sdos>
<sdos>
<sdo>
<description>Host ID</description>
<compareLevel>Ignore</compareLevel>
<datafield>
<description>Host ID</description>
<compareLevel>Ignore</compareLevel>
<offset>2</offset>
<size>1</size>
<readonly>true</readonly>
<isMappedToPdo>false</isMappedToPdo>
<ownerNodeSerial>12102907</ownerNodeSerial>
<ownerSdoIndex>3</ownerSdoIndex>
<data>
<value>ty</value>
<unit></unit>
<min>1</min>
<max>15</max>
</data>
<intValue>2</intValue>
</datafield>
<index>3</index>
<totalbytes>3</totalbytes>
</sdo>
<sdo>
<description>Host ID</description>
<compareLevel>Ignore</compareLevel>
<datafield>
<description>Host ID</description>
<compareLevel>Ignore</compareLevel>
<offset>2</offset>
<size>1</size>
<readonly>true</readonly>
<isMappedToPdo>false</isMappedToPdo>
<ownerNodeSerial>12102906</ownerNodeSerial>
<ownerSdoIndex>4</ownerSdoIndex>
<data>
<value>1.2</value>
<unit></unit>
<min>1</min>
<max>15</max>
</data>
<intValue>2</intValue>
</datafield>
<index>3</index>
<totalbytes>3</totalbytes>
</sdo>
</sdos>
</analogNode>
</nodeGroup>
</nodeGroups>
</channel> </channels> </masterController>
I have created the code below to update values in XML file above. However, my code does not work. Can anyone tell me what might be wrong with my code?
public void updateXml()
{
XElement root = XElement.Load(Server.MapPath("Sample.xml"));
var value = root.Descendants("datafield")
.Where(x => (string)x.Element("ownerNodeSerial") == TextBox1.Text.ToString() &&
(string)x.Element("ownerSdoIndex") == TextBox2.Text.ToString())
.Select(x => (string)x.Element("data").Element("value")).FirstOrDefault();
root.SetElementValue(value, "505");
root.Save("Sample.xml");
Process.Start("Sample.xml");
}
void UpdateBcName(XElement query, object newValue)
{
query.Element("value").SetValue(newValue);
}
IEnumerable<XElement> LoadElementWhereReqNameEquals(XElement root, string reqName)
{
IEnumerable<XElement> queries = from el in root.Descendants("sdo")
where (from add in el.Elements("datafield")
where
(string)add.Element("ownerNodeSerial") == TextBox1.Text &&
(string)add.Element("ownerSdoIndex") == TextBox2.Text
select add).Any()
select el;
return queries;
}
Any help will be appreciated.
Upvotes: 0
Views: 118
Reputation: 1499740
Your use of XElement.SetElementValue
isn't really what you want. You've found the string value of the first value
element (e.g. "2") and then you're using that as the name of the element you want to update. I suspect you actually want:
var valueElement = root.Descendants("datafield")
.Where(x => (string)x.Element("ownerNodeSerial") == TextBox1.Text &&
(string)x.Element("ownerSdoIndex") == TextBox2.Text)
.Select(x => x.Element("data").Element("value"))
.FirstOrDefault();
valueElement.Value = 505;
Note that I've set it to an int
rather than a string, as I strongly suspect it's meant to be logically an integer - let LINQ to XML convert it to a string representation. Likewise I've removed the ToString
calls from TextBox1.Text
and TextBox2.Text
. I'd actually suggest parsing TextBox1.Text
and TextBox2.Text
into int
values (or long
, or whatever) and then compare those:
// TODO: Use int.TryParse instead, to handle invalid input cleanly
int ownerNodeSerial = int.Parse(TextBox1.Text);
int ownerSdoIndex = int.Parse(TextBox2.Text);
var valueElement = root.Descendants("datafield")
.Where(x => (int)x.Element("ownerNodeSerial") == ownerSdoIndex &&
(int)x.Element("ownerSdoIndex") == ownerNodeSerial)
.Select(x => x.Element("data").Element("value"))
.FirstOrDefault();
...
Upvotes: 1