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
74 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 Do You Stack Up Against Your Peers?

With today’s modern enterprise so dependent on digital infrastructures, the impact of major incidents has increased dramatically. Grab the report now to gain insight into how your organization ranks against your peers and learn best-in-class strategies to resolve 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

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

This article describes relatively difficult and non-obvious issues that are likely to arise when creating COM class in Visual Studio and deploying it by professional MSI-authoring tools. It is assumed that the reader is already familiar with the cla…
Many of us here at EE write code. Many of us write exceptional code; just as many of us write exception-prone code. As we all should know, exceptions are a mechanism for handling errors which are typically out of our control. From database errors, t…
Email security requires an ever evolving service that stays up to date with counter-evolving threats. The Email Laundry perform Research and Development to ensure their email security service evolves faster than cyber criminals. We apply our Threat…

749 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