We help IT Professionals succeed at work.

XML structure change after updating data in XML

hallhu
hallhu asked
on
Hi experts,

Can you please help me with the problem regarding XML data updating. I have a problem that the structure of the XML changes after I make an update in XML.
Exactly: From

    <property id="32527" fileAssociated="0">
      <data>
        <string>NAE-01:NAE-01/MSTP_2.FX07_01.AV-0</string>
      </data>
    </property>

To:
    </property>
    <property id="32527" fileAssociated="0">NAE-01:NAE-01/MSTP_2.FX07_01nviTemp_Average</property>

I changed the inner string value and the structure is change also.

 I attached the code, the original and the updated XML file. What I'm doing wrong?
Thanx,

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Xml.Linq;
using System.Text;
using System.Windows.Forms;


namespace NAE_BACNet_Object_Change
{
    public partial class Main : Form
    {
        public Main()
        {
            InitializeComponent();
        }

        private void btnConvert_Click(object sender, EventArgs e)
        {
            XElement XObjectsElements = XElement.Load(@"export.xml");

            lstLog.Clear();
            string strFullReference = "";
            string strObjectName = "";

            foreach (XElement XObjectElement in XObjectsElements.Nodes().OfType<XElement>()) 
            {
                if ((string)XObjectElement.Attribute("classid") == "502" | (string)XObjectElement.Attribute("classid") == "519")
                {
                    foreach (XElement XPropertyElement in XObjectElement.Nodes().OfType<XElement>())
                    {
                        if ((string)XPropertyElement.Attribute("id") == "2390") { strObjectName = XPropertyElement.Value; }
                        if ((string)XPropertyElement.Attribute("id") == "32527")
                        {
                            strFullReference = XPropertyElement.Value;

                            int lastDotPosition = strFullReference.LastIndexOf('.');
                            string strNode = strFullReference.Substring(0, lastDotPosition);
                            string strObject = strFullReference.Substring(lastDotPosition + 1, strFullReference.Length - lastDotPosition - 1);

                            if (lastDotPosition != -1 && strObjectName != strObject)
                            {
                                lstLog.AppendText(String.Format("{0} -> {1}.{2}{3}", XPropertyElement.Value, strNode, strObjectName, Environment.NewLine));
                                XPropertyElement.SetValue(strNode + strObjectName);
                            }
                            else
                            {
                                lstLog.AppendText(String.Format("{0} -> {1}{2}", XPropertyElement.Value, "No Chnage", Environment.NewLine));
                            }
                        }
                    }
                }
            }
            XObjectsElements.Save(@"export.xml");
        }
    }
}

Open in new window

export-original.xml
export-updated.xml
Comment
Watch Question

Most Valuable Expert 2011
Top Expert 2015

Commented:
I can't fully explain to you why this is happening, but I know that it's something to do with accessing the Value property of XPropertyElement. I think in a crude sense, Value gives you all the text (non-node) data within the current node (in this case, XPropertyElement)--including all child levels.

The following is one way you could overcome this--I'm sure there are other ways as well.
' In line 47 of you post, do
XPropertyElement.Element("data").Element("string").SetValue(strNode + strObjectName);

Open in new window

Most Valuable Expert 2011
Top Expert 2015
Commented:
I guess I should have checked the docs before posting  :)

    "Gets or sets the concatenated text contents of this element."

http://msdn.microsoft.com/en-us/library/system.xml.linq.xelement.value.aspx