Member 14329681 Ответов: 2

Извлечение предложений с определенной строкой в узле


Я хочу сделать приложение для извлечения предложений с определенной строкой в узле. Приложение состоит из текстового поля для указания строки, которую нужно искать. При нажатии на кнопку поиска результаты будут отображаться в виде списка. При выборе конкретного элемента из списка будет показан весь текст в элементе, имя узла, имя parentnode и атрибут узла. Проблема возникает, когда узел содержит более одного предложения с определенной строкой. На самом деле приложение не может присвоить соответствующий индекс каждому элементу в списке.
Спасибо за вашу помощь

Что я уже пробовал:

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 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>

Member 14329681

У меня есть проблема с элементами в listBox1. На самом деле я не знаю, как получить одинаковые индексы для предложений в узле для отображения деталей этого узла в элементах управления textBox2 и Label

2 Ответов

Рейтинг:
2

Maciej Los

Взгляните на приведенный ниже код:

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()}");
}


Результат:
Janet is a teacher  3
Nancy is a teacher.  4


Для получения более подробной информации, пожалуйста, смотрите: Классе XDocument (Системы.В формате XML.По LINQ) | Майкрософт Документы[^]


Member 14329681

Благодарю вас за вашу любезность. Но это решение не помогает мне иметь весь текст в элементе и атрибуте узла, выбирая элемент в списке.

Maciej Los

Почему?

Member 14329681

У меня есть проблема с элементами в listBox1. На самом деле я не знаю, как получить одинаковые индексы для предложений в узле для отображения деталей этого узла в элементах управления textBox2 и Label.

Рейтинг:
2

Maciej Los

Скорее, чем ListBox, использовать элемент управления ListView[^] или Практическое руководство[^].

Вот пример для использования с Помощью linqpad[^]. Не стесняйтесь менять его в соответствии с вашими потребностями.

//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;
	}
}