简体   繁体   中英

How can I copy a block of XML from one document to the other?

I have two dataGridViews that load up an XML file each, I have made it so that you can drag and drop rows in between each of the grids. However at the moment, all that it does is copy the data from the dataGridView. This works fine however I need to copy all of the XML that is relevant to that row.

Here is the XML that I have to work with:

<WindowBuilderProject>
  <stringtable>

    <stentry>0..607</stentry> //All of the other records

    <stentry>
      <index>608</index>
      <sid>MNUB_AUTO</sid>
      <val>
        <en>AUTO</en>
      </val>
      <params>
        <fontref>0</fontref>
        <numref>0</numref>
        <clip>FALSE</clip>
        <include>TRUE</include>
        <protected>FALSE</protected>
        <cwidth>-1</cwidth>
        <dwidth>0</dwidth>
      </params>
    </stentry>

  </stringtable>
</WindowBuilderProject>

So I need to copy the XML of the row that the user has selected and insert it into the in the other (same format) XML document.

So far I have this:

string location = "/WindowBuilderProject/stringtable/stentry[index='" + rowIndexOfItemUnderMouseToDrop + "']";
XmlNode Copy = xDoc.ImportNode(xDoc2.SelectSingleNode(location), false);
xDoc.DocumentElement.AppendChild(Copy); //This is just supposed to add it to the end, I will worry about ordering once it works

It runs fine, but all that happens i I get a added to the bottom of the XML file. How can I select the whole block of XML?

Thanks a lot for your help!

Assume you want to copy block of elements from text1.xml to text2.xml, you can use LINQ to XML, example below assumes copying all entries from text1 to text 2:

  var xDoc1 = XDocument.Load("C:\\text1.xml");
  var xDoc2 = XDocument.Load("C:\\text2.xml");

  var doc1Entries = xDoc1.Descendants("stentry");

  var cloneEntries = doc1Entries.Select(x => new XElement(x));
  xDoc2.Descendants("stentry").Last().AddAfterSelf(cloneEntries);

  xDoc2.Save("C:\\text2.xml");

But you also can use Where method to filter to get part of xml, sample below is to filter using list of indices:

  var filterIndices = new[] {600, 601, 700, 705};

  var doc1Entries =
      xDoc1.Descendants("stentry")
           .Where(x =>         
               filterIndices.Contains(int.Parse(x.Element("index").Value)));

In here, I assume to insert to the last using Last , but if you care about ordering, you can use LINQ on xDoc2 to find correct position, then do insert.

Every XmlNode has several methods (and XmlDocument is a child class of XmlNode), so you can use xDoc.SelectNodes() or xDoc.SelectSingleNode() to pick a specific node wherever in the document structure, store that node in an object (let's call it needleNode), and then do xDoc.InsertBefore(Copy, ref needleNode) or xDoc.InsertAfter(Copy, ref needleNode) . Using these four functions you can insert the xml section to absolutely ANY part in the structure of the second xml.

If your control is databound, you don't need to add/remove rows to the DataGridView's rows collection (you actually can't do this). Instead, add them to the underlying datasource collection (the collection you are setting in to the DataSource property of the DataGridView). Afterwards you'll need to refresh the view of both datagridviews to reflect the change.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM