populate a tree view with an xml file - c#

Im using .net windows form application. I have an xml file.I want to populate a tree view with data from a xml file. I am doing this using the following code.
private void button1_Click(object sender, EventArgs e)
{
try
{
this.Cursor = System.Windows.Forms.Cursors.WaitCursor;
//string strXPath = "languages";
string strRootNode = "Treeview Sample";
OpenFileDialog Dlg = new OpenFileDialog();
Dlg.Filter = "All files(*.*)|*.*|xml file (*.xml)|*.txt";
Dlg.CheckFileExists = true;
string xmlfilename = "";
if (Dlg.ShowDialog() == DialogResult.OK)
{
xmlfilename = Dlg.FileName;
}
// Load the XML file.
//XmlDocument dom = new XmlDocument();
//dom.Load(xmlfilename);
XmlDocument doc = new XmlDocument();
doc.Load(xmlfilename);
string rootName = doc.SelectSingleNode("/*").Name;
textBox4.Text = rootName.ToString();
//XmlNode root = dom.LastChild;
//textBox4.Text = root.Name.ToString();
// Load the XML into the TreeView.
this.treeView1.Nodes.Clear();
this.treeView1.Nodes.Add(new TreeNode(strRootNode));
TreeNode tNode = new TreeNode();
tNode = this.treeView1.Nodes[0];
XmlNodeList oNodes = doc.SelectNodes(textBox4.Text);
XmlNode xNode = oNodes.Item(0).ParentNode;
AddNode(ref xNode, ref tNode);
this.treeView1.CollapseAll();
this.treeView1.Nodes[0].Expand();
this.Cursor = System.Windows.Forms.Cursors.Default;
}
catch (Exception ex)
{
this.Cursor = System.Windows.Forms.Cursors.Default;
MessageBox.Show(ex.Message, "Error");
}
}
private void AddNode(ref XmlNode inXmlNode, ref TreeNode inTreeNode)
{
// Recursive routine to walk the XML DOM and add its nodes to a TreeView.
XmlNode xNode;
TreeNode tNode;
XmlNodeList nodeList;
int i;
// Loop through the XML nodes until the leaf is reached.
// Add the nodes to the TreeView during the looping process.
if (inXmlNode.HasChildNodes)
{
nodeList = inXmlNode.ChildNodes;
for (i = 0; i <= nodeList.Count - 1; i++)
{
xNode = inXmlNode.ChildNodes[i];
inTreeNode.Nodes.Add(new TreeNode(xNode.Name));
tNode = inTreeNode.Nodes[i];
AddNode(ref xNode, ref tNode);
}
}
else
{
inTreeNode.Text = inXmlNode.OuterXml.Trim();
}
}
My xml file is this:"hello.xml"
<?xml version="1.0" encoding="utf-8" ?>
<languages>
<language>
<key>abc</key>
<value>hello how ru</value>
</language>
<language>
<key>def</key>
<value>i m fine</value>
</language>
<language>
<key>ghi</key>
<value>how abt u</value>
</language>
</languages>
Now after using the above code I am able to populate the tree view. But I dont like to populate the complete xml file. I should get only till
languages
language
key
value
I don't want
abc
how are you
etc.....
I mean to say the leaf nodes. Please help me

What you don't want to add is the text content of the nodes, if I understood correctly; then, you might check the NodeType property of the XmlNode class, something like:
xNode = inXmlNode.ChildNodes[i];
if (xNode.NodeType != XmlNodeType.Text) {
inTreeNode.Nodes.Add(new TreeNode(xNode.Name));
tNode = inTreeNode.Nodes[i];
AddNode(ref xNode, ref tNode);
}

Related

parsing old xml to make a new one-document already has a root node c#

I have a XML file that is uploaded in a treeView and I have to make a new XML by treating old nodes as text and wrapping them with new tags and then saving it all into a file.I have to keep in mind which nodes are the child nodes and give them element tags.
private void saveNode(TreeNode node, XmlNode xnode,XmlDocument xmlDoc1)
{
foreach (TreeNode tnode in treeView1.Nodes)
{
xnode.AppendChild(xmlDoc1.CreateNode(XmlNodeType.Text, tnode.Text, tnode.Text));
XmlNode rootNode = xmlDoc1.CreateElement("category");
XmlAttribute oid = rootNode.Attributes.Append(xmlDoc1.CreateAttribute("oid"));
oid.Value = Guid.NewGuid().ToString();
xmlDoc1.AppendChild(rootNode);
XmlElement dr = (XmlElement)rootNode.AppendChild(xmlDoc1.CreateElement("name"));
dr.AppendChild(xmlDoc1.CreateTextNode("Model"));
XmlElement com = (XmlElement)rootNode.AppendChild(xmlDoc1.CreateElement("comment"));
XmlElement condition = (XmlElement)rootNode.AppendChild(xmlDoc1.CreateElement("condition"));
xmlDoc1.AppendChild(rootNode);
saveNode(tnode, xnode,xmlDoc1);
if (node.NextNode != null)
{
foreach (TreeNode tn in treeView1.Nodes)
{
XmlNode root1 = xmlDoc1.CreateElement("elements");
root1.AppendChild(xmlDoc1.CreateNode(XmlNodeType.Text, tnode.Text, "elements"));
root1.InnerText = tnode.Text;
saveNode(tn, xnode, xmlDoc1);
}
}
else {
foreach (TreeNode tn in treeView1.Nodes)
{
XmlNode root1 = xmlDoc1.CreateElement("elements");
root1.AppendChild(xmlDoc1.CreateNode(XmlNodeType.Text, tnode.Text, "elements"));
saveNode(tn, xnode, xmlDoc1);
}
}
}
}
private void saveToolStripMenuItem_Click(object sender, EventArgs e)
{
XmlDocument xmlDoc1 = new XmlDocument();
XmlNode xroot = xmlDoc1.CreateElement("model");
XmlAttribute oid = xroot.Attributes.Append(xmlDoc1.CreateAttribute("oid"));
oid.Value = Guid.NewGuid().ToString();
xmlDoc1.AppendChild(xroot);
XmlElement dr = (XmlElement)xroot.AppendChild(xmlDoc1.CreateElement("name"));
dr.AppendChild(xmlDoc1.CreateTextNode("Model"));
XmlElement com = (XmlElement)xroot.AppendChild(xmlDoc1.CreateElement("comment"));
XmlElement condition = (XmlElement)xroot.AppendChild(xmlDoc1.CreateElement("condition"));
XmlElement el = (XmlElement)xroot.AppendChild(xmlDoc1.CreateElement("element"));
try
{
foreach (TreeNode tn in treeView1.Nodes)
{
saveNode(tn, xroot,xmlDoc1);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
saveFileDialog1.Filter = "Text Files (*.xml)|*.xml";
saveFileDialog1.AddExtension = true;
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{
xmlDoc1.Save(saveFileDialog1.FileName);
}
}

XML represantation of treeview nodes

I am trying to import and export to treeview from XML file. But i am having this issue. sample treeview have one root node and two child nodes of same parent. The codes i am using for exporting and importing doesn't work. When I export the treeview the saved XML file is like this:
<?xml version="1.0" encoding="utf-8" ?>
<AAA>
BBBCCC</AAA>
When I import that xml file to treeview it look like this after import xml to treeview . Codes that i am using for export and import are:
//Open the XML file, and start to populate the treeview
private void populateTreeview()
{
OpenFileDialog dlg = new OpenFileDialog();
dlg.Title = "Open XML Document";
dlg.Filter = "XML Files (*.xml)|*.xml";
dlg.FileName = Application.StartupPath + "\\..\\..\\example.xml";
if (dlg.ShowDialog() == DialogResult.OK)
{
try
{
//Just a good practice -- change the cursor to a
//wait cursor while the nodes populate
this.Cursor = Cursors.WaitCursor;
//First, we'll load the Xml document
XmlDocument xDoc = new XmlDocument();
xDoc.Load(dlg.FileName);
// Now, clear out the treeview,
// and add the first (root) node
treeView1.Nodes.Clear();
treeView1.Nodes.Add(new TreeNode(xDoc.DocumentElement.Name));
TreeNode tNode = new TreeNode();
tNode = (TreeNode)treeView1.Nodes[0];
// We make a call to addTreeNode,
// where we'll add all of our nodes
addTreeNode(xDoc.DocumentElement, tNode);
// Expand the treeview to show all nodes
treeView1.ExpandAll();
}
catch(XmlException xExc)
{
// Exception is thrown is there is an error in the Xml
MessageBox.Show(xExc.Message);
}
catch(Exception ex) //General exception
{
MessageBox.Show(ex.Message);
}
finally
{
this.Cursor = Cursors.Default; //Change the cursor back
}
}
}
// This function is called recursively until all nodes are loaded
private void addTreeNode(XmlNode xmlNode, TreeNode treeNode)
{
XmlNode xNode;
TreeNode tNode;
XmlNodeList xNodeList;
if (xmlNode.HasChildNodes) // The current node has children
{
xNodeList = xmlNode.ChildNodes;
for(int x = 0; x <= xNodeList.Count - 1; x++)
{
// Loop through the child nodes
xNode = xmlNode.ChildNodes[x];
treeNode.Nodes.Add(new TreeNode(xNode.Name));
tNode = treeNode.Nodes[x];
addTreeNode(xNode, tNode);
}
}
else //No children, so add the outer xml (trimming off whitespace)
treeNode.Text = xmlNode.OuterXml.Trim();
}
private XmlTextWriter xr;
public void exportToXml2(TreeView tv, string filename)
{
xr = new XmlTextWriter(filename, System.Text.Encoding.UTF8);
xr.WriteStartDocument();
//Write our root node
xr.WriteStartElement(treeView1.Nodes[0].Text);
foreach (TreeNode node in tv.Nodes)
{
saveNode2(node.Nodes);
}
//Close the root node
xr.WriteEndElement();
xr.Close();
}
private void saveNode2(TreeNodeCollection tnc)
{
foreach (TreeNode node in tnc)
{
// If we have child nodes, we'll write
// a parent node, then iterate over
// the children
if (node.Nodes.Count > 0)
{
xr.WriteStartElement(node.Text);
saveNode2(node.Nodes);
xr.WriteEndElement();
}
else //No child nodes, so we just write the text
{
xr.WriteString(node.Text);
}
}
}
Where is the problem?
You are using language other than English . please convert and save .
var text = File.ReadAllText(file, Encoding.GetEncoding(codePage));
how-to-read-text-files-with-ansi-encoding-and-non-english-letters
File.WriteAllText(filepath, filetext, Encoding.Unicode);
or
new System.IO.StreamWriter(new FileStream(file_name,FileMode.OpenOrCreate),Encoding.ASCII);
read-write-text-file-ansi-utf8-unicode
how-to-convert-utf7-string-into-ansi-in-csharp
The code is fine. The xml should look like this
<?xml version="1.0" encoding="utf-8" ?>
<AAA>
<BBB/>
<CCC/>
</AAA>
ok, I modified a few lines and I managed what i want to.
Firstly, I add char array for special characters. And use them for trim() function.
private void addTreeNode(XmlNode xmlNode, TreeNode treeNode)
{
**char[] karakter = new char[] { '<', '>', '/' };**
XmlNode xNode;
TreeNode tNode;
XmlNodeList xNodeList;
if (xmlNode.HasChildNodes) //The current node has children
{
xNodeList = xmlNode.ChildNodes;
for (int x = 0; x <= xNodeList.Count - 1; x++)
{
xNode = xmlNode.ChildNodes[x];
treeNode.Nodes.Add(new TreeNode(xNode.Name));
tNode = treeNode.Nodes[x];
addTreeNode(xNode, tNode);
}
}
else
{
treeNode.Text = xmlNode.OuterXml.Trim(**karakter**);
}
secondly, if there is no child nodes I used WriteRaw method instead of WriteString method.Because special characters are replaced by WriteString method.
private void saveNode2(TreeNodeCollection tnc)
{
foreach (TreeNode node in tnc)
{
if (node.Nodes.Count > 0)
{
xr.WriteStartElement(node.Text);
saveNode2(node.Nodes);
xr.WriteEndElement();
}
else
{
**xr.WriteRaw($"<{node.Text}/>");**
}
}
But when I try to save treeview with two roots, It doesn't write the last root. Any opinion? Childs of last root is written as childs of first root. Other then that codes work.

How do I store values from textbox in C#

I created this program to get texts from textboxes and store in a xml file but it doesn't store. Also if I close the form and reopen it and enter data again how can it update the same existing file without replacing the previous data.? please fix my code
private void button1_Click(object sender, EventArgs e)
{
string name = this.txtName.Text;
string occupation = this.txtOccupation.Text;
string dob = this.txtDob.Text;
string nic = this.txtNic.Text;
double id = double.Parse(this.lblID.Text);
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.CreateXmlDeclaration("1.0", "utf-8", "yes");
XmlNode rootNode = xmlDoc.CreateElement("Users");
XmlNode subNode = xmlDoc.CreateElement("Users");
XmlAttribute nameAtt = xmlDoc.CreateAttribute("Name");
nameAtt.Value = name;
XmlAttribute occupationAtt = xmlDoc.CreateAttribute("Occupation");
occupationAtt.Value = occupation;
XmlAttribute dobAtt = xmlDoc.CreateAttribute("Date of Birth");
dobAtt.Value = dob;
XmlAttribute nicAtt = xmlDoc.CreateAttribute("NIC");
nicAtt.Value = nic;
XmlAttribute idAtt = xmlDoc.CreateAttribute("ID");
idAtt.Value = idAtt.ToString();
subNode.Attributes.Append(nameAtt);
subNode.Attributes.Append(occupationAtt);
subNode.Attributes.Append(dobAtt);
subNode.Attributes.Append(nicAtt);
subNode.Attributes.Append(idAtt);
rootNode.AppendChild(subNode);
subNode.AppendChild(rootNode);
xmlDoc.Save("E:/Data.xml");
Hide();
}
}
}
This is just a simple working example based on the code you provided, but probably there are better ways to accomplish what you are trying to do:
private void button1_Click(object sender, EventArgs e)
{
string name = this.txtName.Text;
string occupation = this.txtOccupation.Text;
string dob = this.txtDob.Text;
string nic = this.txtNic.Text;
double id = double.Parse(this.lblID.Text);
// XML file path.
string xmlPath = "E:/Data.xml";
XmlDocument xmlDoc = new XmlDocument();
// If specified file does not exist, create a new one.
if (!File.Exists(xmlPath))
{
XmlDeclaration xmlDeclaration = xmlDoc.CreateXmlDeclaration("1.0", "UTF-8", "yes");
XmlElement rootNode = xmlDoc.DocumentElement;
xmlDoc.InsertAfter(xmlDeclaration, rootNode);
XmlNode parentNode = xmlDoc.CreateElement("Users");
XmlNode subNode = xmlDoc.CreateElement("User");
XmlAttribute nameAtt = xmlDoc.CreateAttribute("Name");
nameAtt.Value = name;
XmlAttribute occupationAtt = xmlDoc.CreateAttribute("Occupation");
occupationAtt.Value = occupation;
XmlAttribute dobAtt = xmlDoc.CreateAttribute("Date_Of_Birth");
dobAtt.Value = dob;
XmlAttribute nicAtt = xmlDoc.CreateAttribute("NIC");
nicAtt.Value = nic;
XmlAttribute idAtt = xmlDoc.CreateAttribute("ID");
idAtt.Value = id.ToString();
subNode.Attributes.Append(nameAtt);
subNode.Attributes.Append(occupationAtt);
subNode.Attributes.Append(dobAtt);
subNode.Attributes.Append(nicAtt);
subNode.Attributes.Append(idAtt);
xmlDoc.AppendChild(parentNode);
parentNode.AppendChild(subNode);
// Save new XML file.
xmlDoc.Save(xmlPath);
}
// If specified file exists, read and update it.
else
{
// Open existing XML file.
xmlDoc.Load(xmlPath);
// Set to true if current name is already found in the XML file,
// of course it should be better to check the ID instead the name,
// supposing that ID is unique.
bool nameFound = false;
// Get all "User" nodes and check if one of them already contains
// the specified name.
foreach (XmlNode user in xmlDoc.SelectNodes("Users/User"))
{
if (user.Attributes.GetNamedItem("Name").Value == name)
{
nameFound = true;
break;
}
}
// If the name is not already in the file, insert a new user
// with that name.
if (nameFound == false)
{
XmlNode subNode = xmlDoc.CreateElement("User");
XmlAttribute nameAtt = xmlDoc.CreateAttribute("Name");
nameAtt.Value = name;
XmlAttribute occupationAtt = xmlDoc.CreateAttribute("Occupation");
occupationAtt.Value = occupation;
XmlAttribute dobAtt = xmlDoc.CreateAttribute("Date_Of_Birth");
dobAtt.Value = dob;
XmlAttribute nicAtt = xmlDoc.CreateAttribute("NIC");
nicAtt.Value = nic;
XmlAttribute idAtt = xmlDoc.CreateAttribute("ID");
idAtt.Value = id.ToString();
subNode.Attributes.Append(nameAtt);
subNode.Attributes.Append(occupationAtt);
subNode.Attributes.Append(dobAtt);
subNode.Attributes.Append(nicAtt);
subNode.Attributes.Append(idAtt);
xmlDoc.SelectSingleNode("Users").AppendChild(subNode);
xmlDoc.Save(xmlPath);
}
}
}
And this is a sample output XML file:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Users>
<User Name="John" Occupation="student" Date_Of_Birth="1990" NIC="NIC" ID="123" />
<User Name="David" Occupation="professor" Date_Of_Birth="1973" NIC="NIC" ID="452" />
</Users>

Get innertext from XML tags?

I am trying to populate an array with the inner text or value of a XML tag. I can loop though the nodes of the tag i am just having an issue pulling out the stored value.
I am looping though the child nodes of the Properties Tag, XML at bottom of Question.
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load("C://Users//Shaun//Documents//Visual Studio 2010//Projects//LightStoneTestService//LightStoneTestService//FileTest//Testdo.xml");
//XmlNodeList dataNodes = xmlDoc.SelectNodes("//Properties");
XmlNodeList oXMlNodeList = xmlDoc.GetElementsByTagName("Properties");
for (int Count = 0; Count < 27; Count++)
{
foreach (XmlNode node in oXMlNodeList)
{
int Max = node.ChildNodes.Count;
foreach (XmlNode childNode in node.ChildNodes) //For each child node in FieldData
{
if (ArrayProperties[Count].LightStoneTag == childNode.Name)
{
ArrayProperties[Count].Value = node.SelectSingleNode(ArrayProperties[Count].LightStoneTag).InnerText;
}
}
}
}
***** My Xml file looks as follows:
<NewDataSet>
<RequestData xmlns="RequestData">
<Req_ID>3204eba5-07f4-4e83-8b46-d89fa1d70bf6</Req_ID>
</RequestData>
<Properties xmlns="Properties">
<sr_id>19374324</sr_id>
<prop_id>9841107</prop_id>
<DEED_ID>21</DEED_ID>
<PROPTYPE_ID>2</PROPTYPE_ID>
<SS_ID>2315</SS_ID>
<NAD_ID>3048001</NAD_ID>
<property_type>SS</property_type>
<PROVINCE>GA</PROVINCE>
<MUNICNAME>CITY OF JOHANNESBURG</MUNICNAME>
<DEEDTOWN>ALLENS NEK</DEEDTOWN>
<SECTIONAL_TITLE>SS GREENHILLS</SECTIONAL_TITLE>
<UNIT>15</UNIT>
<TownShip>ALLENS NEK</TownShip>
<Purchase_Price>236500</Purchase_Price>
<Purchase_Date>20031020</Purchase_Date>
<Bond_Number>SB37369/2006</Bond_Number>
<Township_alt>ALLEN'S NEK EXT 32</Township_alt>
<RE>false</RE>
</Properties>
</NewDataSet>
It's the namespace issue. Add this portion of code before the for loop:
NameTable nt = new NameTable();
nt.Add("Properties");
XmlNamespaceManager nsmgr = new XmlNamespaceManager(nt);
nsmgr.AddNamespace("ns1", "Properties");
Change the line where you retrieve InnerText to:
ArrayProperties[Count].Value = node
.SelectSingleNode(
String.Concat("//ns1:", ArrayProperties[Count].LightStoneTag),
nsmgr)
.InnerText;

How to set attribute to an XML element using linq to xml in C#

i've an xml file like
<Root>
<Steps>
<Step Test="SampleTestOne" Status="Fail" />
<Step Test="SampleTestTwo" Status="Fail" />
</Steps>
</Root>
i need to change or overwrite the attribute value of "Status" in the Step element.
Now i'm using XmlDocument for this
like
XmlDocument XDoc = new XmlDocument();
XDoc.Load(Application.StartupPath + "\\Sample.xml");
XmlNodeList NodeList = XDoc.SelectNodes("//Steps/Step");
foreach (XmlNode Node in NodeList)
{
XmlElement Elem = (XmlElement)Node;
String sTemp = Elem.GetAttribute("Test");
if (sTemp == "SampleTestOne")
Elem.SetAttribute("Status", "Pass");
}
I need search the element and to update the status
is there any way to do this using XDocumentin c#
Thanks in advance
string filename = #"C:\Temp\demo.xml";
XDocument document = XDocument.Load(filename);
var stepOnes = document.Descendants("Step").Where(e => e.Attribute("Test").Value == "SampleTestOne");
foreach (XElement element in stepOnes)
{
if (element.Attribute("Status") != null)
element.Attribute("Status").Value = "Pass";
else
element.Add(new XAttribute("Status", "Pass"));
}
document.Save(filename);
You can use this code:
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(xmlFile);
XmlNode node = xmlDoc.SelectSingleNode("Root/Steps/Step");
node.Attributes["Status"].Value = "True";
xmlDoc.Save(xmlFile);

Categories