none
linq to xml ...merge 2 xml docs

    Question

  • okay gurus....

    I've done my due diligence on this one but just can't find the answer I'm looking for...  I have an XML document that holds recipe records.  I would like to merge another xml file with additional recipesinto my master xml document.  I have worked out the code to add the file.... my problem is that I would like to check if the file already exists before I add it to my master xml... here's the code I have to add the new file to the master

     Sub mergexml()
            Try
    
                'Merge the two Xmls
                Dim addrecipe As XElement
                Dim query = addingdoc.Descendants("RECIPES")
    
                addrecipe = New XElement("RECIPES", query)
    
                doc.Element("RECIPES").Add(addrecipe)
    
            Catch ex As Exception
                MessageBox.Show("Error merging Xml Documents")
            End Try

    so.... I want to add to this xml document ("doc")

    <?xml version="1.0" encoding="UTF-8"?> <RECIPES> -<RECIPE> <NAME>MAMAS PIE</NAME> <STYLE>OLD FASHIONED</STYLE> <CHEF>MAMA</CHEF> <DATE>10</DATE> -<INGREDIENTS> -<APPLES> -<APPLE> <NAME>Gala</NAME> <QUANTITY>2</QUANTITY> <COLOR>pink</COLOR> <SWEETNESS>4</SWEETNESS> </APPLE> -<APPLE> <NAME>MACINTOSH</NAME> <QUANTITY>3</QUANTITY> <COLOR>RED</COLOR> <SWEETNESS>1</SWEETNESS> </APPLE> -<APPLE> <NAME>GOLDEN DELICIOUS</NAME> <QUANTITY>4</QUANTITY> <COLOR>GOLD</COLOR> <SWEETNESS>2</SWEETNESS> </APPLE> </APPLES>

    -<SUGARS> -<SUGAR> <NAME>TRUCKLE</NAME> <COLOR>BROWN</COLOR> <PRICE>2.25</PRICE> </SUGAR> </SUGARS> </INGREDIENTS> </RECIPE>

    -<RECIPE> <NAME>DADS PIE</NAME> <STYLE>NEW AGE</STYLE> <CHEF>DAD</CHEF> <DATE>15</DATE> -<INGREDIENTS> -<APPLES> -<APPLE> <NAME>GALA</NAME> <COLOR>PINK</COLOR> <SWEETNESS>3</SWEETNESS> </APPLE> -<APPLE> <NAME>GRANNY SMITH</NAME> <COLOR>GOLD</COLOR> <SWEETNESS>4</SWEETNESS> </APPLE> -<APPLE> <NAME>Golden Delicious</NAME> <SWEETNESS>4</SWEETNESS> <COLOR>gold</COLOR> </APPLE> </APPLES>

    -<SUGARS> -<SUGAR> <NAME>CANE</NAME> <COLOR>WHITE</COLOR> <PRICE>1.5</PRICE> </SUGAR> </SUGARS> </INGREDIENTS> </RECIPE>

    </RECIPES>

    this xml document.... but only the distinct elements

    <?xml version="1.0" encoding="UTF-8"?> <RECIPES> -<RECIPE> <NAME>DADS PIE</NAME> <STYLE>NEW AGE</STYLE> <CHEF>DAD</CHEF> <DATE>15</DATE> -<INGREDIENTS> -<APPLES> -<APPLE> <NAME>GALA</NAME> <COLOR>PINK</COLOR> <SWEETNESS>3</SWEETNESS> </APPLE> -<APPLE> <NAME>GRANNY SMITH</NAME> <COLOR>GOLD</COLOR> <SWEETNESS>4</SWEETNESS> </APPLE> -<APPLE> <NAME>Golden Delicious</NAME> <SWEETNESS>4</SWEETNESS> <COLOR>gold</COLOR> </APPLE> </APPLES>

    -<SUGARS> -<SUGAR> <NAME>CANE</NAME> <COLOR>WHITE</COLOR> <PRICE>1.5</PRICE> </SUGAR> </SUGARS> </INGREDIENTS> </RECIPE>

    -<RECIPE> <NAME>PETES PIE</NAME> <STYLE>OLD FASHIONED</STYLE> <CHEF>MAMA</CHEF> <DATE>12</DATE> -<INGREDIENTS> -<APPLES> -<APPLE> <NAME>MACINTOSH</NAME> <COLOR>RED</COLOR> <SWEETNESS>1</SWEETNESS> </APPLE> -<APPLE> <NAME>GOLDEN DELICIOUS</NAME> <COLOR>GOLD</COLOR> <SWEETNESS>2</SWEETNESS> </APPLE> </APPLES>

    -<SUGARS> -<SUGAR> <NAME>TRUCKLE</NAME> <COLOR>BROWN</COLOR> <PRICE>2.25</PRICE> </SUGAR> </SUGARS> </INGREDIENTS> </RECIPE> </RECIPES>

    so.... essentially, I'm looking to merge these files and exclude the file that already exists.... (in this case "DADS PIE")

    Thanks

    Pete

    • Moved by Alexander Sun Thursday, October 25, 2012 3:19 AM Move to more appropriate forum. (From:LINQ Project General)
    Wednesday, October 24, 2012 1:57 AM

Answers

  • Hi Pete;

    The following code snippet will do what you are asking for.

    ' Get the xml files from the file system
    Dim master = XDocument.Load("C:\Your Working Directory\MastRecipes.xml")
    Dim addThese = XDocument.Load("C:\Your Working Directory\AddRecipes.xml")
    ' Get all the RECIPE nodes from each file.
    Dim mRecipes = master.Descendants("RECIPE")
    Dim aRecipes = addThese.Descendants("RECIPE")
    ' Find all the name nodes in aRecipes that are not in mRecipes.
    Dim recipesToAdd = aRecipes.Select(Function(m) m.Element("NAME").Value).Except(mRecipes.Select(Function(m) m.Element("NAME").Value))
    ' Get a reference to all thenodes that need to be added
    Dim elementsToAdd = aRecipes.Where(Function(a) recipesToAdd.Contains(a.Element("NAME")))
    ' Now add those nodes to the master xml file
    master.Root.Add(elementsToAdd)
    master.Save("C:\Your Working Directory\MastRecipesUpdated.xml")

      


    Fernando (MCSD)

    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".

    • Marked as answer by peteepoo Friday, November 02, 2012 2:42 AM
    Wednesday, October 24, 2012 11:21 PM

All replies

  • Hi Pete;

    What are you considering distinct? For example one recipe for "Dads Pie" may have different child elements. So is distinct that all nodes for "Dads Pie" be equal? If not what should be done then?

      


    Fernando (MCSD)

    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".

    Wednesday, October 24, 2012 4:14 PM
  • Thanks Fernando,
    Right now, I'm concerned about the name only....  I've worked out a method that works pretty well when I add only single recipes at a time. I use a LINQ query searching for the name element and only add it if it does not exist in the master document.

    WHat I would like to do is merge 2 XML files that have several recipes each.... but only add recipes with distinct NAME elements.

    Thanks

    Wednesday, October 24, 2012 8:34 PM
  • Hi Pete;

    The following code snippet will do what you are asking for.

    ' Get the xml files from the file system
    Dim master = XDocument.Load("C:\Your Working Directory\MastRecipes.xml")
    Dim addThese = XDocument.Load("C:\Your Working Directory\AddRecipes.xml")
    ' Get all the RECIPE nodes from each file.
    Dim mRecipes = master.Descendants("RECIPE")
    Dim aRecipes = addThese.Descendants("RECIPE")
    ' Find all the name nodes in aRecipes that are not in mRecipes.
    Dim recipesToAdd = aRecipes.Select(Function(m) m.Element("NAME").Value).Except(mRecipes.Select(Function(m) m.Element("NAME").Value))
    ' Get a reference to all thenodes that need to be added
    Dim elementsToAdd = aRecipes.Where(Function(a) recipesToAdd.Contains(a.Element("NAME")))
    ' Now add those nodes to the master xml file
    master.Root.Add(elementsToAdd)
    master.Save("C:\Your Working Directory\MastRecipesUpdated.xml")

      


    Fernando (MCSD)

    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".

    • Marked as answer by peteepoo Friday, November 02, 2012 2:42 AM
    Wednesday, October 24, 2012 11:21 PM
  • That worked perfectly... thanks
    Friday, November 02, 2012 2:42 AM
  •  

    Not a problem peteepoo, glad I was able to help.

      


    Fernando (MCSD)

    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".

    Friday, November 02, 2012 3:19 AM