简体   繁体   中英

How can I update xml file element value within elements

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.

Your use of XElement.SetElementValue isn't really what you want. You've found the string value of the first value element (eg "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();
...

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