Как запросить эти два файла XML с помощью C #? - PullRequest
5 голосов
/ 13 октября 2010

Я создаю небольшое приложение (телефонную книгу), на самом деле Я уже создал его, используя ms access в качестве базы данных, но сейчас я изучаю XML и планирую использовать его в качестве базы данных для этого приложения (просто для развлечения и в образовательных целях).

Вот схема в моей базе данных доступа.

alt text

И я создал два XML-файла с той же структурой, что и для двух таблиц доступа.

Таблица контактов

<?xml version="1.0" standalone="yes"?>
<ContactList>
  <xs:schema id="ContactList" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xs:element name="ContactList" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
      <xs:complexType>
        <xs:choice minOccurs="0" maxOccurs="unbounded">
          <xs:element name="Contact">
            <xs:complexType>
              <xs:sequence>
                <xs:element name="ContactID" type="xs:int" minOccurs="0" />
                <xs:element name="Name" type="xs:string" minOccurs="0" />
              </xs:sequence>
            </xs:complexType>
          </xs:element>
        </xs:choice>
      </xs:complexType>
    </xs:element>
  </xs:schema>
  <Contact>
    <ContactID>1</ContactID>
    <Name>Peter</Name>
  </Contact>
  <Contact>
    <ContactID>2</ContactID>
    <Name>John</Name>
  </Contact>
</ContactList>

Таблица контактных номеров

<?xml version="1.0" standalone="yes"?>
<ContactNumbers>
  <xs:schema id="ContactNumbers" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xs:element name="ContactNumbers" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
      <xs:complexType>
        <xs:choice minOccurs="0" maxOccurs="unbounded">
          <xs:element name="Numbers">
            <xs:complexType>
              <xs:sequence>
                <xs:element name="ContactID" type="xs:int" minOccurs="0" />
                <xs:element name="Mobile" type="xs:string" minOccurs="0" />
                <xs:element name="Office" type="xs:string" minOccurs="0" />
                <xs:element name="Home" type="xs:string" minOccurs="0" />
              </xs:sequence>
            </xs:complexType>
          </xs:element>
        </xs:choice>
      </xs:complexType>
    </xs:element>
  </xs:schema>
  <Numbers>
    <ContactID>1</ContactID>
    <Mobile>+63-9277-392607</Mobile>
    <Office>02-890-2345</Office>
    <Home>0</Home>
  </Numbers>
  <Numbers>
    <ContactID>2</ContactID>
    <Mobile>+62-9277-392607</Mobile>
    <Office>02-890-2345</Office>
    <Home>1</Home>
  </Numbers>
</ContactNumbers>

Вот так должно выглядеть мое простое приложение:

alt text

В своем исходном приложении я использовал оператор INNER JOIN для получения контактных номеров определенного контакта. Но теперь я понятия не имею, как это сделать, поскольку я использую 2 XML-файла в качестве таблиц (соответствующих двум таблицам доступа ms). Можно ли по-прежнему запрашивать и связывать эти два XML-файла и достигать той же функциональности, что и моя первая версия приложения (с использованием доступа)?

Пока это то, что у меня есть только:

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

namespace TestXML
{
    public partial class Form1 : Form
    {
        OpenFileDialog openFileDialog1 = new OpenFileDialog();
        DataSet ds = new DataSet();
        DataView dv = new DataView();

        public Form1()
        {
            InitializeComponent();
        }

        private void btnBrowse_Click(object sender, EventArgs e)
        {
            try
            {
                openFileDialog1.Filter = "XML Document (*.xml)|*.xml";
                openFileDialog1.FileName = "";
                openFileDialog1.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
                if (openFileDialog1.ShowDialog() == DialogResult.OK)
                {
                    txtDirectory.Text = openFileDialog1.FileName;                    
                    btnLoad.Enabled = true;
                }
            }
            catch (Exception x)
            {
                btnLoad.Enabled = false;
                MessageBox.Show("Something went wrong! \n" + x.Message, "Ooops!", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
        }

        private void btnLoad_Click(object sender, EventArgs e)
        {
            dgContactList.DataSource = LoadXML();
        }

        private DataView LoadXML()
        {
            try
            {
                ds.Clear();
                ds.ReadXml(txtDirectory.Text, XmlReadMode.ReadSchema);
                dv = ds.Tables[0].DefaultView;
                lblStatus.Text = "XML is loaded successfully";
            }
            catch (Exception x)
            {
                MessageBox.Show("Something went wrong! \n" + x.Message, "Ooops!", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                lblStatus.Text = "";
            }
            return dv;
        }
    }
}

Ответы [ 2 ]

1 голос
/ 13 октября 2010

Вот мое решение (MainList - ваш первый XML, а DetailedList - второй.)

using System;
using System.Linq;
using System.Windows.Forms;
using System.Xml.Linq;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog OpenFD = new OpenFileDialog();
            OpenFD.InitialDirectory = Application.StartupPath;
            OpenFD.FileName = "";
            OpenFD.ShowDialog();
            if (OpenFD.FileName == "")
                return;
            textBox1.Text = OpenFD.FileName;
            ReadXMLFile(OpenFD.FileName);
        }
        private void ReadXMLFile(String strFileName)
        {
            var X = XDocument.Load(strFileName).Descendants("Contact").Select(N => new
        {
            ID = N.Element("ContactID").Value,
            Name=N.Element("Name").Value 
        });
        foreach (var XX in X)
        {
            dataGridView1.Rows.Add(XX.ID, XX.Name);
        }
    }


    private void dataGridView1_RowHeaderMouseDoubleClick(object sender, DataGridViewCellMouseEventArgs e)
    {
        String St = dataGridView1.SelectedRows[0].Cells[0].Value.ToString();
        var Data = XDocument.Load(Application.StartupPath + "\\DetailedList.xml").Descendants("Numbers")
                         .Where(X=>X.Element("ContactID").Value ==St)
                         .Select(N => new
                          {
                              Mobile = N.Element("Mobile").Value,
                              Office = N.Element("Office").Value,
                              Home = N.Element("Home").Value
                          });
        dataGridView2.Rows.Clear();
        foreach (var X in Data)
        {
            dataGridView2.Rows.Add(X.Mobile,X.Office,X.Home);
        }
    }
}
}

Вывод

Result

Добавитьнеобходимое свойство для gridViews

Я создал columns во время разработки.

И вместо foreach мы можем wse LAMBDA Expression Надеюсь, вы поймете.... Пожалуйста, дайте мне знать, если у вас есть isses.

Наслаждайтесь !!!!!

0 голосов
/ 13 октября 2010

Мне лично не нравится работать с DataView, DataTable и так далее. Я бы создал классы, которые соответствуют вашим XML-данным. Например. Контакт и номера. Затем я прочитал бы данные, используя XDocument с синтаксисом XML LINQ. Вы создаете коллекцию контактов, которую вы собираетесь установить в первом GridView, и после щелчка просто читаете выбранный объект из коллекции и задаете данные во втором GridView.

Нет необходимости во внутренних объединениях, все определено в классах и явно лучше читается. Просто мнение.

EDIT:

Больше информации:

Создание классов, представляющих ваши данные, например, Контакт, номера

Читать о XDocument в MSDN.

Пример:

XDocument contactDoc = XDocument.Load(m_helpTopicFile);
var contacts = from xmlTopic in contactDoc.Descendants("Contact")
select new Contact
                     {
                         Id = int.Parse(xmlTopic.Element("ContactID").Value, CultureInfo.InvariantCulture),
                         Name = xmlTopic.Element("name").Value,

                     };

Затем установите это в качестве источника данных с помощью contacts.ToList ()

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...