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
65 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
3 Use Cases for Connected Systems

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, testing some more, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us.

 

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

3 Use Cases for Connected Systems

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, testing some more, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us.

Question has a verified solution.

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

Parsing a CSV file is a task that we are confronted with regularly, and although there are a vast number of means to do this, as a newbie, the field can be confusing and the tools can seem complex. A simple solution to parsing a customized CSV fi…
Real-time is more about the business, not the technology. In day-to-day life, to make real-time decisions like buying or investing, business needs the latest information(e.g. Gold Rate/Stock Rate). Unlike traditional days, you need not wait for a fe…
This Micro Tutorial will give you a basic overview how to record your screen with Microsoft Expression Encoder. This program is still free and open for the public to download. This will be demonstrated using Microsoft Expression Encoder 4.
This Micro Tutorial demonstrates using Microsoft Excel pivot tables, how to reverse engineer competitors' marketing strategies through backlinks.

776 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