Click here to Skip to main content
15,886,963 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I want to make an application to retrieve sentences with a certain string in a node. The application consists of a TextBox for specifying the string to look for. Upon clicking the search button the results will be displayed in a listBox. Selecting a particular item from the listBox will show the whole text in the element, the name of node, name of parentnode and the attribute of the node. The problem arises when the node contains more than one sentences with a certain string. In fact application can not assign appropriate index to each of item in listBox.
Thanks for your helpfullness

What I have tried:

C#
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Linq;
using System.Collections;

namespace ttt3
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

       XmlNodeList list = null;
       XmlDocument doc = new XmlDocument();
        
        private void button1_Click(object sender, EventArgs e)
        {
           // XmlDocument doc = new XmlDocument();
            doc.Load(Application.StartupPath + "/XMLFile1.xml");
            list = doc.SelectNodes(@"employees/employee[contains(firstname,'" +
textBox1.Text + "')]");
        
           listBox1.Items.Clear();
           
                foreach (XmlNode node in list)
                {
                    int index = 0;
                   
                    string temp = node["firstname"].InnerText;
                    string keyword =textBox1.Text;
                   
                  string[] temps =temp.Split('.');
                 
                    for (int index1 = 0; index1 < temps.Length; index1++ )
                       
 if(temps[index1].Contains(keyword))
 {
  
     listBox1.Items.Add(temps[index1]);

          while (index != -1)
                        {
                            index = temp.IndexOf(keyword, index + 1);
                        }
 }

                      
	}

             }
        
        private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
          
                    textBox2.Text = list[listBox1.SelectedIndex].ChildNodes[0].InnerText;
                   label1.Text = list[listBox1.SelectedIndex].ChildNodes[0].LocalName;
                    label2.Text = list[listBox1.SelectedIndex].ParentNode.LocalName;
                    label3.Text = list[listBox1.SelectedIndex].Attributes[0].Value;                                  
     }

        private void textBox2_TextChanged(object sender, EventArgs e)
        {

        }
    }
}

XML
<?xml version="1.0" encoding="utf-8" ?>

<!-- This is list of employees -->
<employees>
  <employee employeeid="1">
    <firstname> Nancy includes a BA in psychology from Colorado State University. She also completed. Nancy is a member of
Toastmasters International. </firstname>
   </employee>
  <employee employeeid="2">
    <firstname>Nancy is a student.</firstname>
  </employee>
  <employee employeeid="3">
    <firstname>Janet is a teacher</firstname>
  </employee>
 <employee employeeid="4">
    <firstname>Nancy is a teacher.</firstname>
  </employee>
</employees>
Posted
Updated 30-Jan-20 23:43pm
v2
Comments
Member 14329681 31-Jan-20 2:00am    
I have a problem with the items in listBox1. In fact I don't know how to gain same indices for sentences in a node for displaying details of that node in the textBox2 and Label controls

Take a look at below code:
C#
string xcontent = @"<?xml version='1.0' encoding='utf-8' ?>
<!-- This is list of employees -->
<employees>
  <employee employeeid='1'>
    <firstname> Nancy includes a BA in psychology from Colorado State University. She also completed. Nancy is a member of
Toastmasters International. </firstname>
   </employee>
  <employee employeeid='2'>
    <firstname>Nancy is a student.</firstname>
  </employee>
  <employee employeeid='3'>
    <firstname>Janet is a teacher</firstname>
  </employee>
 <employee employeeid='4'>
    <firstname>Nancy is a teacher.</firstname>
  </employee>
</employees>";


//use Load("fullFileName.xml") method instead of Parse()
XDocument xdoc = XDocument.Parse(xcontent);

string keyword = "teacher";

List<XElement> result = xdoc.Descendants("firstname")
	.Where(x=>x.Value.ToString().Contains(keyword))
	.Select(x=>x)
	.ToList();

foreach(XElement ele in result)
{
	Console.WriteLine($"{ele.Value}\t{ele.Parent.Attribute("employeeid").Value.ToString()}");
}


Result:
Janet is a teacher  3
Nancy is a teacher.  4


For further details, please see: XDocument Class (System.Xml.Linq) | Microsoft Docs[^]
 
Share this answer
 
Comments
Member 14329681 30-Jan-20 12:41pm    
Thank you for your helpfulness. But this solution does not help me to have whole text in the element and the attribute of the node by choosing an item in a listBox.
Maciej Los 30-Jan-20 13:29pm    
Why?
Member 14329681 31-Jan-20 1:57am    
I have a problem with the items in listBox1. In fact I don't know how to gain same indices for sentences in a node for displaying details of that node in the textBox2 and Label controls.
Rather than ListBox, use ListView[^] or DataGridView[^].

Here is an example to use with LinqPad[^]. Feel free to change it to your needs.

C#
//use {F4} to add references to: System.Windows.Forms.dll
//add below namespaces:
//System.Drawing
//System.Windows.Forms

Form f = null;
ListView LvXmlData = null;
TextBox tb1 = null;
TextBox tb2 = null;

void Main()
{
	f = CreateForm();
	f.Show();
}

// Define other methods and classes here
private Form CreateForm()
{
	Form frm = new Form()
	{
		Text = "Listbox example",
		Size = new Size(800,600),
		MinimizeBox = false,
		MaximizeBox = false,
		SizeGripStyle = SizeGripStyle.Hide
	};
	
	SplitContainer sc = new SplitContainer()
	{
		Name = "sc",
		Dock = DockStyle.Fill,
		Parent = frm
	};
	
	LvXmlData = new ListView()
	{
		Name = "LvXmlData",
		Size = new Size(200, 500),
		Dock = DockStyle.Top,
		View = View.Details,
		MultiSelect = false,
		FullRowSelect = true,
		Parent = sc.Panel1
	};
	LvXmlData.Columns.Add("Id");
	LvXmlData.Columns.Add("FirstName");
	LvXmlData.SelectedIndexChanged += new EventHandler(LvXmlData_SelectedIndexChanged);

	sc.SplitterDistance = 440;

	for(int i=0; i<2; i++)
	{
		Label lbl = new Label(){Text = i==0 ? "Id" : "FirstName", Location = new Point(4, (24*i)+10), AutoSize = true, Parent = sc.Panel2};
		if(i==0)
			tb1 = new TextBox(){Name = "TxtId",Location = new Point(90, (24*i)+8), Size = new Size(240, 24), Parent = sc.Panel2};
		else
			tb2 = new TextBox(){Name = "TxtFirstName",Location = new Point(90, (24*i)+8), AutoSize = false, Multiline=true, Size = new Size(240, 120), Parent = sc.Panel2};
	}
	
	
	Button btnLoad = new Button()
	{
		Size = new Size(120, 38),
		Location = new Point(10, 510),
		Text = "Load xml data",
		Parent = sc.Panel1
	};
	btnLoad.Click += new System.EventHandler(BtnLoadData_Click);

	return frm;
}

private void BtnLoadData_Click(object sender, EventArgs ea)
{
	string xcontent = @"<?xml version='1.0' encoding='utf-8' ?>
		<!-- This is list of employees -->
		<employees>
		  <employee employeeid='1'>
		    <firstname> Nancy includes a BA in psychology from Colorado State University. She also completed. Nancy is a member of
		Toastmasters International. </firstname>
		   </employee>
		  <employee employeeid='2'>
		    <firstname>Nancy is a student.</firstname>
		  </employee>
		  <employee employeeid='3'>
		    <firstname>Janet is a teacher</firstname>
		  </employee>
		 <employee employeeid='4'>
		    <firstname>Nancy is a teacher.</firstname>
		  </employee>
		</employees>";

	//use Load("fullFileName.xml") method instead of Parse()
	XDocument xdoc = XDocument.Parse(xcontent);
	
	var result = xdoc.Descendants("firstname")
		.Select(x=> new {Id = x.Parent.Attribute("employeeid").Value.ToString(), FirstName = x.Value})
		.ToList();
	
	LvXmlData.BeginUpdate();
	foreach(var ele in result)
	{
		LvXmlData.Items.Add(ele.Id).SubItems.Add(ele.FirstName);
	}
	LvXmlData.Columns[0].Width = -1;
	LvXmlData.Columns[1].Width = -1;
	LvXmlData.EndUpdate();
}

private void LvXmlData_SelectedIndexChanged(object sender, System.EventArgs e)
{
	if(LvXmlData.SelectedItems.Count==1)
	{
	   	// Get the currently selected item in the ListView 
		ListViewItem item = LvXmlData.SelectedItems[0];
		//and display data
		tb1.Text = item.SubItems[0].Text;
		tb2.Text = item.SubItems[1].Text;
	}
}
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900