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
77 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 3
6 Comments
 
LVL 11

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 11

Expert Comment

by:louisfr
ID: 41829332
Which version of VB are you using?
Yield requires at least VB10 (Visual Studio 2012)
0
Forrester Webinar: xMatters Delivers 261% ROI

Guest speaker Dean Davison, Forrester Principal Consultant, explains how a Fortune 500 communication company using xMatters found these results: Achieved a 261% ROI, Experienced $753,280 in net present value benefits over 3 years and Reduced MTTR by 91% for tier 1 incidents.

 

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 11

Accepted Solution

by:
louisfr earned 500 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

Learn by Doing. Anytime. Anywhere.

Do you like to learn by doing?
Our labs and exercises give you the chance to do just that: Learn by performing actions on real environments.

Hands-on, scenario-based labs give you experience on real environments provided by us so you don't have to worry about breaking anything.

Question has a verified solution.

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

The ECB site provides FX rates for major currencies since its inception in 1999 in the form of an XML feed. The files have the following format (reducted for brevity) (CODE) There are three files available HERE (http://www.ecb.europa.eu/stats/exch…
This article shows how to deploy dynamic backgrounds to computers depending on the aspect ratio of display
There are cases when e.g. an IT administrator wants to have full access and view into selected mailboxes on Exchange server, directly from his own email account in Outlook or Outlook Web Access. This proves useful when for example administrator want…
Michael from AdRem Software explains how to view the most utilized and worst performing nodes in your network, by accessing the Top Charts view in NetCrunch network monitor (https://www.adremsoft.com/). Top Charts is a view in which you can set seve…

688 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