?
Solved

How do I compare two xml files and remove all data elements in file2 not found in file1 using VB.NET

Posted on 2016-10-03
6
Medium Priority
?
87 Views
Last Modified: 2016-10-10
Hello,

If I have required data elements in file1, how do I remove all data elements in file2 not include in file1 and include all data elements in file1.

For example, if required data elements are in file1 and I am compare it against file2, how do I create file3.


File1.xml
 <?xml version="1.0" encoding="utf-8"?>
 <Root>
 <Table1>
   <Receiver></Receiver>
   <AGD></AGD>
 <NSC></NSC>
   <FCT></FCT>
   <FCI></FCI>
   <KBZ></KBZ>
 </Table1>
</Root>

Fil2.xml
<Root>
 <Table1>
   <Link_ID>1</Link_ID>
   <Receiver>BEL</Receiver>
   <AGD>M5</AGD>
 <NSC>M2</NSC>
   <FCT>M88</FCT>
   <FCI>M69</FCI>
  <NFZ>M10</NFZ>
 </Table1>
 <Table1>
   <Link_ID>2</Link_ID>
   <Receiver>USA</Receiver>
   <AGD>M5</AGD>
 <NSC><M2</NSC>
   <FCT></FCT>
   <FCI></FCI>
 <NFZ>M11</NFZ>
 </Table1>
 <Table1>
   <Link_ID>3</Link_ID>
   <Receiver>DNK</Receiver>
   <AGD>M58</AGD>
 <NSC>M29</NSC>
   <FCT>M48</FCT>
   <FCI>M99</FCI>
  <NFZ>M17</NFZ>
 </Table1>
 <Table1>
   <Link_ID>4</Link_ID>
   <Receiver>BEL</Receiver>
   <AGD>M57</AGD>
 <NSC><M28</NSC>
   <FCT>99</FCT>
   <FCI>97</FCI>
 <NFZ>M11</NFZ>
 </Table1>
 </Root>


 File3.xml

<Root>
 <Table1>
   <Link_ID>1</Link_ID>
   <Receiver>BEL</Receiver>
   <AGD>M5</AGD>
 <NSC>M2</NSC>
   <FCT>M88</FCT>
   <FCI>M69</FCI>
  <KBZ></KBZ>
 </Table1>
 <Table1>
   <Link_ID>2</Link_ID>
   <Receiver>USA</Receiver>
   <AGD>M5</AGD>
 <NSC><M2</NSC>
   <FCT></FCT>
   <FCI></FCI>
  <KBZ></KBZ>
 </Table1>
 <Table1>
   <Link_ID>3</Link_ID>
   <Receiver>DNK</Receiver>
   <AGD>M58</AGD>
 <NSC>M29</NSC>
   <FCT>M48</FCT>
   <FCI>M99</FCI>
   <KBZ></KBZ>
 </Table1>
 <Table1>
   <Link_ID>4</Link_ID>
   <Receiver>BEL</Receiver>
   <AGD>M57</AGD>
 <NSC><M28</NSC>
   <FCT>99</FCT>
   <FCI>97</FCI>
 <KBZ></KBZ>
 </Table1>
 </Root>
0
Comment
Question by:vcharles
  • 3
  • 3
6 Comments
 
LVL 12

Expert Comment

by:louisfr
ID: 41828194
Here is a way, using a left outer join in LINQ:
    Sub Main()
        Dim template = XDocument.Load("d:/temp/file1.xml")
        Dim source = XDocument.Load("d:/temp/File2.xml")
        Dim dest = GetElements(source.Root, template.Root)
        With New XDocument(dest)
            .Save("d:/temp/File3.xml")
        End With
    End Sub
    Iterator Function GetElements(source As XElement, template As XElement) As IEnumerable(Of XElement)
        If source Is Nothing Then
            Yield New XElement(template)
        Else
            Dim x = New XElement(template.Name, From t In template.Elements()
                                                Group Join s In source.Elements() On t.Name Equals s.Name Into j = Group
                                                From s In j.DefaultIfEmpty()
                                                Select GetElements(s, t))
            Dim Text = source.Nodes().OfType(Of XText)
            If Text.Any Then
                x.AddFirst(Text)
            Else
                x.AddFirst("")
            End If
            Yield x
        End If
    End Function

Open in new window

0
 

Author Comment

by:vcharles
ID: 41828794
Hi,

I tried to modify your code to use it on a button click event but the "Yield" give me an error, variable not defined. How do I fix this error?

Private Sub Button8_Click_1(sender As System.Object, e As System.EventArgs) Handles Button8.Click

        Dim template = XDocument.Load("d:/temp/file1.xml")
        Dim source = XDocument.Load("d:/temp/File2.xml")
        Dim dest = GetElements(source.Root, template.Root)
        With New XDocument(dest)
            .Save("d:/temp/File3.xml")
        End With
    End Sub
   


    Public Function GetElements(source As XElement, template As XElement) As IEnumerable(Of XElement)

        If source Is Nothing Then
            Yield(New XElement(template))
        Else
            Dim x = New XElement(template.Name, From t In template.Elements()
                                                Group Join s In source.Elements() On t.Name Equals s.Name Into j = Group
                                                From s In j.DefaultIfEmpty()
                                                Select GetElements(s, t))
            Dim Text = source.Nodes().OfType(Of XText)()
            If Text.Any Then
                x.AddFirst(Text)
            Else
                x.AddFirst("")
            End If
            Yield(x)
        End If
    End Function

Thanks,

Victor
0
 
LVL 12

Expert Comment

by:louisfr
ID: 41829332
Which version of VB are you using?
Yield requires at least VB10 (Visual Studio 2012)
0
 [eBook] Windows Nano Server

Download this FREE eBook and learn all you need to get started with Windows Nano Server, including deployment options, remote management
and troubleshooting tips and tricks

 

Author Comment

by:vcharles
ID: 41830334
I am using VS2010 professional version.
0
 

Author Comment

by:vcharles
ID: 41831091
Hi, do you have a solution that works with VS 2010?

Victor
0
 
LVL 12

Accepted Solution

by:
louisfr earned 2000 total points
ID: 41831244
That code doesn't even need an iterator.
I started typing with an iterator in mind and only return one element at a time.
Here's a new version.
    Function GetElements(source As XElement, template As XElement) As XElement
        If source Is Nothing Then
            Return New XElement(template)
        Else
            Dim x = New XElement(template.Name, From t In template.Elements()
                                                Group Join s In source.Elements() On t.Name Equals s.Name Into j = Group
                                                From s In j.DefaultIfEmpty()
                                                Select GetElements(s, t))
            Dim Text = source.Nodes().OfType(Of XText)
            If Text.Any Then
                x.AddFirst(Text)
            Else
                x.AddFirst("")
            End If
            Return x
        End If
    End Function

Open in new window

0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This document covers how to connect to SQL Server and browse its contents.  It is meant for those new to Visual Studio and/or working with Microsoft SQL Server.  It is not a guide to building SQL Server database connections in your code.  This is mo…
It’s quite interesting for me as I worked with Excel using vb.net for some time. Here are some topics which I know want to share with others whom this might help. First of all if you are working with Excel then you need to Download the Following …
The Relationships Diagram is a good way to get an overall view of what a database is keeping track of. It is also where relationships are defined. A relationship specifies how two tables connect to each other. As you build tables in Microsoft Ac…
How can you see what you are working on when you want to see it while you to save a copy? Add a "Save As" icon to the Quick Access Toolbar, or QAT. That way, when you save a copy of a query, form, report, or other object you are modifying, you…

578 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question