none
Multiple XML files RRS feed

  • Question

  • I have two related tables in two XML files. I want to use them to populate a single DataGridView control. I can't use a XMLDataDocument, because it only supports a single file. I need to have two files because one is for fixed data that is uniform for all users, while the other is specific to the current user. For each item, I need to display both the fixed data columns and the current-user columns in the same grid. What is the best approach to binding these files to the DataGridView?

    thanks

    Mike
    Saturday, February 2, 2008 9:43 PM

All replies

  • If it were me, I'd merge the two XML documents into one (via an XSLT transform), create an XmlDataDocument on the merged document, and then split the document back into two (via two XSLT transforms, one for each XML document) when editing was complete.  This is relatively easy to do if the XML documents are straightforward enough (like if they've been created by DataSet.WriteXml) and if XSLT is something you're conversant in, though it'd be quite a learning experience if it isn't.

     

    If not, an alternate possibility would be to pull the data from both XML documents into a temporary DataTable object, and bind the DataGridView to that (via a BindingSource).  I'd build two Dictionary<DataRow, XmlElement> collections (one for each XML document) at the same time.  Then I'd handle the DataRowChanged event on the DataTable.  I'd make the event handler look up the XmlElement(s) for the DataRow that changed and post the changes back to the XmlElement.

    Monday, February 4, 2008 2:34 AM
  • Hi Robert,
    Thanks for the thoughtful response.
     Robert Rossney wrote:

    If it were me, I'd merge the two XML documents into one (via an XSLT transform), create an XmlDataDocument on the merged document, and then split the document back into two (via two XSLT transforms, one for each XML document) when editing was complete.  This is relatively easy to do if the XML documents are straightforward enough (like if they've been created by DataSet.WriteXml) and if XSLT is something you're conversant in, though it'd be quite a learning experience if it isn't.

    I'm conversant in XSLT, but I'd avoided this approach because I'm concerned about the overhead. The (relatively small) per-user data will change every time the program is run, while the (many megabytes) shared data is constant. I'd hate to have to write out the shared data every time just for the XSLT transform to throw it away.

    [quote  user="Robert Rossney"]

    If not, an alternate possibility would be to pull the data from both XML documents into a temporary DataTable object, and bind the DataGridView to that (via a BindingSource).  I'd build two Dictionary<DataRow, XmlElement> collections (one for each XML document) at the same time.  Then I'd handle the DataRowChanged event on the DataTable.  I'd make the event handler look up the XmlElement(s) for the DataRow that changed and post the changes back to the XmlElement.


    This sounds more like what I'm looking for. How would I load both documents into the DataTable object?

    Thanks again,

    Mike
    Monday, February 4, 2008 4:01 AM
  • It occurs to me:  if your shared data is constant, why not just decorate it with the user data?  For instance, if your shared data looks like this:

     

    Code Snippet

    <Record>

       <ID>1</ID>

       <Field1>foo</Field1>

       <Field2>bar</Field2>

    </Record>

     

     

    and your user data looks like this:

     

    Code Snippet

    <Record>

       <ID>1</ID>

       <Field3>bat</Field3>

    </Record>

     

    it should be straightforward enough to run through your shared data and add Field3 elements to each Record element containing the user's data.  Then you create an XmlDataDocument, let the user manipulate it in the UI, and then, at the end, go back through the shared data, remove the Field3 elements, and put their values back in the user XML.

     

    But wait.  If the shared data isn't being updated, creating DataTables and putting them in a DataSet is the way to go.

     

    Create a DataTable containing the shared data, with ID as its primary key.  Create a second DataTable containing the user data, with ID as its primary key.  Populate the tables from the XML.  Add both of them to a DataSet.  Create a DataRelation between the two tables, so that the shared data is the parent of the user data, with the ID in the user data being the foreign key.

     

    Now, in your user data table, create one DataColumn for each non-ID column in the parent table, and set the columns' Expression property to "Parent.Blague", where "Blague" is the name of the column in the shared data.  You now have a user data table whose calculated columns pull data dynamically from the shared data table.

     

    The sweet thing about this approach is that since the shared data is static, you only need to create its DataTable once.  If your shared data is static enough, you can use WriteXml to write out the DataSet (remove the user table first!), and then all copies of your application can start by reading it in.

     

    I hope this makes some kind of sense. 

    Monday, February 4, 2008 10:02 AM