开发者

How to query this two XML files using C#?

I’m creating a small application (a phonebook), actually I already created it using ms access as a database, but now, I’m learning XML and planning to use it as a database for this app (just for fun and educational purposes).

Here’s the diagram in my access database.

How to query this two XML files using C#?

And I created two XML files with the same structure as for the two access tables.

ContactList Table

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

ContactNumbers Table

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

This is how my simple app should look like:

How to query this two XML files using C#?

In my original app, I used INNER JOIN statement to retrieve the contact numbers of a particular contact. But now, I have no idea how to do it since I’m using 2 XML files as the tables (corresponding to th开发者_开发百科e two ms access tables). Is it still possible to query and link these two XML files and achieved the same functionality as my first application (using access) version does?

For now, this is what I only have:

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


Here is my solution(MainList is your 1st XML and DetailedList is the second.)

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

Output

How to query this two XML files using C#?

Add the necessary property to both the gridViews

I've created the columns at the design time.

And Instead of foreach we can wse LAMBDA Expression Hope you will understand.... Please let me know if you have any isses.

Enjoy!!!!!


I personally don't like to work with DataView, DataTable and so on. I would created classes that correspond to your XML data. Eg. Contact and Numbers. Then I would read in the data using XDocument with XML LINQ syntax. You create a collection of contacts that you are going to set on the first GridView, and after clicking you just read the selected object from the collection and set the data on the second GridView.

No need for inner joins, everything is defined in classes and clearly better readable. Just an opinion.

EDIT:

More Infos:

Create classes that represent your data, e.g. Contact, Numbers

Read about XDocument at MSDN.

Example:

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,

                     };

Then set this as the DataSource by using contacts.ToList()

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜