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
51 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 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
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 

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

Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

Join & Write a Comment

For those of you who don't follow the news, or just happen to live under rocks, Microsoft Research released a beta SDK (http://www.microsoft.com/en-us/download/details.aspx?id=27876) for the Xbox 360 Kinect. If you don't know what a Kinect is (http:…
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…
Internet Business Fax to Email Made Easy - With eFax Corporate (http://www.enterprise.efax.com), you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, fr…
This video discusses moving either the default database or any database to a new volume.

758 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

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now