2010-10-13 27 views
5

Estoy creando una pequeña aplicación (una agenda telefónica), en realidad Ya la creé usando ms access como base de datos, pero ahora estoy aprendiendo XML y planificando usarlo como base de datos para esta aplicación (solo por diversión) y propósitos educativos).¿Cómo consultar estos dos archivos XML usando C#?

Aquí está el diagrama en mi base de datos de acceso.

alt text

y yo creamos dos archivos XML con la misma estructura que para las dos tablas de acceso.

lista de contactos Tabla

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

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

Así es como mi sencilla aplicación debe verse como:

alt text

En mi aplicación original, utilicé la declaración INNER JOIN para recuperar los números de contacto de un contacto en particular. Pero ahora, no tengo idea de cómo hacerlo ya que estoy usando 2 archivos XML como tablas (correspondientes a las dos tablas de acceso de ms). ¿Todavía es posible consultar y vincular estos dos archivos XML y lograr la misma funcionalidad que mi primera aplicación (con acceso)?

Por ahora, esto es lo que sólo tengo:

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

Respuesta

1

Aquí está mi solución (MainList es su primera XML y DetailedList es el segundo.)

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

salida

Result

Añadir la propiedad necesaria tanto para la gridViews

He creado el columns en el momento del diseño.

Y en lugar de foreach podemos wse LAMBDA Expression Espero que lo entienda .... Por favor, hágame saber si tiene alguna emisión.

¡¡¡Disfruta !!!!!

+0

¡Guau! jeje, muchas gracias señor por su respuesta :). Estoy muy contento de que alguien haya publicado una respuesta, y funciona. Aunque no es tan fácil de entender, especialmente para justo como yo, principiante. Pero leeré más y jugaré con tu código, todo lo que quiero es tener un ejemplo para poder estudiarlo y servir de base para construir una aplicación y codificación más avanzada, poco a poco. Gracias de nuevo :) – yonan2236

+0

Apenas entiendo 'LAMDA Expression' – yonan2236

0

personalmente no me gusta trabajar con DataView, DataTable y así sucesivamente. Creé clases que corresponden a tus datos XML. P.ej. Contacto y Números. Luego, leería en los datos usando XDocument con la sintaxis XML LINQ. Usted crea una colección de contactos que va a establecer en el primer GridView y, después de hacer clic, simplemente lee el objeto seleccionado de la colección y establece los datos en el segundo GridView.

Sin necesidad de uniones internas, todo está definido en clases y claramente mejor legible. Solo una opinion

EDIT:

Más Info:

crear clases que representan los datos, por ejemplo, Contacto, Números

Lea sobre XDocument en MSDN.

Ejemplo:

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, 

        }; 

asentando después esto como el origen de datos mediante el uso de contacts.ToList()

+0

solo un principiante ... No tengo idea de lo que dijiste ... jeje – yonan2236

+0

He editado mi respuesta, espero que esto ayude – testalino

Cuestiones relacionadas