Avatar of Victor  Charles
Victor CharlesFlag for United States of America

asked on 

Help with transfering data from LinkTemp.xml to Link.xml

Hello,

I am displaying data in several controls from a LinkTemp.xml files for a particular Link_ID. My goal is to transfer records from LinkTemp.xml to Link.xml when the user presses the Transfer button. How do I transfer the data to Link.xml for a particular record?  For example:

LinkTemp displays data based on the following data:
<LinkTemp>
<LinkTemp_ID>1<LinkTemp_ID>
<Receiver_ID>3<Receiver_ID>
<Donor_ID>4</Donor_ID>
</LinkTemp>
<LinkTemp>
<LinkTemp_ID>2<LinkTemp_ID>
<Receiver_ID>6<Receiver_ID>
<Donor_ID>4</Donor_ID> 
</LinkTemp>
<LinkTemp>
<LinkTemp_ID>1<LinkTemp_ID>
<Receiver_ID>3<Receiver_ID>
<Donor_ID>4</Donor_ID> 
</LinkTemp>

Open in new window


If data is being displayed for LinkTemp_ID = 2, when the user presses the Transfer button, I need to transfer values from LinkTemp.xml
<LinkTemp_ID>2<LinkTemp_ID>
<Receiver_ID>6<Receiver_ID>
<Donor_ID>4</Donor_ID> 

Open in new window

 
To Link.xml as:
<Link_ID>2<Link_ID>
<Receiver_ID>6<Receiver_ID>
<Donor_ID>4</Donor_ID> 

Open in new window


Below is the code that I’m using to display the data from LinkTemp.xml amnd to move to next records. When I press Transfer, regardless of which record I’m displaying. As mentioned, How do I modify the code to save the ID values to Link.xml?

A.
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        DonorStream.Load(Application.StartupPath & "/Donor.xml") 'My.Resources.Donor)
        RecStream.Load(Application.StartupPath & "/receiver.xml") 'My.Resources.Receiver)
        LinkStream.Load(Application.StartupPath & "/link.xml") 'My.Resources.Link)
        BindNames()
        FillCombos()

    End Sub


Public Sub BindNames()

        Dim lnk As XmlNodeList = LinkStream.SelectNodes("Root/LinkTemp")
        Dim RecName As XmlNodeList = RecStream.SelectNodes("Root/Receiver")
        Dim DonorName As XmlNodeList = DonorStream.SelectNodes("Root/Donor")

        Dim donorlst As New DataTable()
        donorlst.Columns.Add("ID")
        donorlst.Columns.Add("Name")
        Dim reclst As New DataTable
        reclst.Columns.Add("ID")
        reclst.Columns.Add("Name")

        For Each n As XmlNode In lnk
            Dim rID As Integer = Val(n.ChildNodes(0).InnerText)
            Dim dID As Integer = Val(n.ChildNodes(1).InnerText)

            For Each node As XmlNode In RecName
                If node.ChildNodes(0).InnerText = rID.ToString Then
                    reclst.Rows.Add(New Object() {rID, node.ChildNodes(1).InnerText})
                End If
            Next

            For Each node As XmlNode In DonorName
                If node.ChildNodes(0).InnerText = dID.ToString Then
                    donorlst.Rows.Add(New Object() {node.ChildNodes(0).InnerText, node.ChildNodes(1).InnerText})
                    'Exit For
                End If
            Next
        Next

        CmbDonor.DataSource = donorlst
        CmbDonor.DisplayMember = "Name"
        CmbDonor.ValueMember = "ID"

        CmbRec.DataSource = reclst
        CmbRec.DisplayMember = "Name"
        CmbRec.ValueMember = "ID"
    End Sub

Public Sub FillCombos()
        Dim RecName As XmlNodeList = RecStream.SelectNodes("Root/Receiver")
        Dim DonorName As XmlNodeList = DonorStream.SelectNodes("Root/Donor")

        Dim donorlst As New DataTable()
        donorlst.Columns.Add("ID")
        donorlst.Columns.Add("Name")
        Dim reclst As New DataTable
        reclst.Columns.Add("ID")
        reclst.Columns.Add("Name")

        For Each node As XmlNode In RecName
            reclst.Rows.Add(New Object() {node.ChildNodes(0).InnerText, node.ChildNodes(1).InnerText})
        Next

        For Each node As XmlNode In DonorName
            donorlst.Rows.Add(New Object() {node.ChildNodes(0).InnerText, node.ChildNodes(1).InnerText})
        Next

        donorlst.DefaultView.Sort = "Name ASC"
        CmbDonor.DataSource = donorlst
        CmbDonor.DisplayMember = "Name"
        CmbDonor.ValueMember = "ID"

        reclst.DefaultView.Sort = "Name ASC"
        CmbRec.DataSource = reclst
        CmbRec.DisplayMember = "Name"
        CmbRec.ValueMember = "ID"

        ComboDonor.DataSource = donorlst
        ComboDonor.DisplayMember = "Name"
        ComboDonor.ValueMember = "ID"

        ComboReceiver.DataSource = reclst
        ComboReceiver.DisplayMember = "Name"
        ComboReceiver.ValueMember = "ID"

    End Sub

Open in new window


B. Move to Next record
Private Sub Next_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Next.Click
        Dim NodeCount As Integer = LinkStream.SelectNodes("Root/Link").Count

        If (NodeNumber < NodeCount) Then
            NodeNumber += 1   'Move to some next node
            Dim node As XmlNode = LinkStream.SelectSingleNode("Root/Link[" & NodeNumber & "]")
            Dim Subnode1 As XmlNode = node.ChildNodes(0)
            Dim Subnode2 As XmlNode = node.ChildNodes(1)

            CmbRec.SelectedIndex = Val(Subnode1.InnerText) - 1
            CmbDonor.SelectedIndex = Val(Subnode2.InnerText) - 1
        Else
            NodeNumber = 0   ' Reset count so start searching from zero (You can change strategy)
        End If
    End Sub

Open in new window


Thanks,

Victor
ASP.NETXMLVisual Basic.NET

Avatar of undefined
Last Comment
Victor Charles
Avatar of MikeToole
MikeToole
Flag of United Kingdom of Great Britain and Northern Ireland image

I would probably approach this using XElement variables and LINQ.
It would be easier if you'd made the Element names more consistent between your XML objects.
You Have (by the way, your xml syntax is wrong - you're missing the / before some closing Element names
<LinkTemp>
<LinkTemp_ID>1<LinkTemp_ID>
<Receiver_ID>3<Receiver_ID>
<Donor_ID>4</Donor_ID>
</LinkTemp>
Why not have
<Links>
   <Link>
      <ID>1</ID>
      <Receiver_ID>3</Receiver_ID>
      <Donor_ID>4</Donor_ID>
   </Link>
</Links>

Anyway, then it would be easy to use XML and LINQ to move elements between XElement instances.
ASKER CERTIFIED SOLUTION
Avatar of MikeToole
MikeToole
Flag of United Kingdom of Great Britain and Northern Ireland image

Blurred text
THIS SOLUTION IS ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial
Avatar of Victor  Charles

ASKER

Hi,

I don't understand why you are hard coding:

Dim XT As XElement =
                <Links>
                    <LinkTemp>
                        <LinkTemp_ID>1</LinkTemp_ID>
                        <Receiver_ID>3</Receiver_ID>
                        <Donor_ID>4</Donor_ID>
                    </LinkTemp>
                    <LinkTemp>
                        <LinkTemp_ID>2</LinkTemp_ID>
                        <Receiver_ID>6</Receiver_ID>
                        <Donor_ID>4</Donor_ID>
                    </LinkTemp>
                    <LinkTemp>
                        <LinkTemp_ID>11</LinkTemp_ID>
                        <Receiver_ID>3</Receiver_ID>
                        <Donor_ID>4</Donor_ID>
                    </LinkTemp>
                </Links>
        Dim ID = 2

Shouldn't you be able to use XT after you load the file (i.e.  LinkStream.Load(Application.StartupPath & "/link.xml") 'My.Resources.Link)

I showed the examples of the content of the XML files, but I didn'yt intend to use them as part of my code. Sorry for confusing the situation.

Victor
Avatar of MikeToole
MikeToole
Flag of United Kingdom of Great Britain and Northern Ireland image

Victor,
This was just to get some sample data into the code without going to the bother of creating/loading a file.
The code just demonstrates the ease of using LINQ to XML to select a node and then construct a new node from the data retrieved.
It would be even easier if the XML element names matched between the two documents as there would then be no need to map the names.
Mike
Avatar of Victor  Charles

ASKER

Ok, I got it.

Can you please help me with filtering the data, in Link.xml for some reason:
For Each n As XmlNode In LinkStream.SelectNodes("/root/link[ReceiverID=" & Me.TextBox2.Text & "]")
does not work.

Code:
Dim MyLink As XDocument = XDocument.Load(Server.MapPath("~/App_Data/Link.xml"))
        ''Loop Through all records in Link.xml and assign first childnode the rID and second childnode to dID
        For Each n As XmlNode In LinkStream.SelectNodes("/root/link[ReceiverID=" & Me.TextBox2.Text & "]")
            Dim rID As Integer = Val(n.ChildNodes(0).InnerText)
            Dim dID As Integer = Val(n.ChildNodes(1).InnerText)

            ' 'Loop Through all records in Receiver.xml and if ReceiverID = Textbox2.text and if the firstnode
            For Each node As XmlNode In RecName

                If node.ChildNodes(0).InnerText = rID.ToString Then
                    reclst.Rows.Add(New Object() {rID, node.ChildNodes(0).InnerText})
                End If

            Next

            For Each node As XmlNode In DonorName
                If node.ChildNodes(0).InnerText = dID.ToString Then
                    donorlst.Rows.Add(New Object() {dID, node.ChildNodes(1).InnerText})
                    ''donorlst.Rows.Add(New Object() {dID, node.ChildNodes(1).InnerText})
                End If
            Next
        Next
Avatar of Victor  Charles

ASKER

Hello,

I understand your code now, unfortunately, it's saving the data to LinkTemp.xml, I need to save the data selected from LinkTemp.xml to Link.xml. Both Link and LinkTemp files have the same format for example if you picked the values for ID=2 in Link.xml, its related values for receiver_ID and DonorID should be appended to Link.xml.
LinkTemp.xml
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Root>
  <LinkTemp>
   <LinkTemp_ID>1</LinkTemp_ID>
    <ReceiverID>1</ReceiverID>
    <DonorID>2</DonorID>
  </LinkTemp>
  <LinkTemp>
    <LinkTemp_ID>2</LinkTemp_ID>  *****Data Selected
    <ReceiverID>2</ReceiverID>
    <DonorID>3</DonorID>
  </LinkTemp>
 <LinkTemp>
    <LinkTemp_ID>3</LinkTemp_ID>
    <ReceiverID>3</ReceiverID>
    <DonorID>4</DonorID>
 </LinkTemp>
<LinkTemp>
    <LinkTempID>4</LinkTemp_ID>
    <ReceiverID>4</ReceiverID>
    <DonorID>5</DonorID>
  </LinkTemp>
 <LinkTemp>
    <LinkTemp_ID>5</LinkTemp_ID>
    <ReceiverID>5</ReceiverID>
    <DonorID>1</DonorID>
  </LinkTemp>
</Root>

If the user selects the record where LinkTemp_ID = 2 from LinkTemp.xml, Link.xml should appear as follows:

Link.xml
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Root>
  <Link>
   <Link_ID>1</Link_ID>
    <ReceiverID>1</ReceiverID>
    <DonorID>2</DonorID>
  </Link>
  <Link>
    <Link_ID>2</Link_ID>   ***Data Transfered
    <ReceiverID>2</ReceiverID>
    <DonorID>3</DonorID>
  </Link>
</Root>
Avatar of MikeToole
MikeToole
Flag of United Kingdom of Great Britain and Northern Ireland image

>>>> XT.Add(GetNodeForID.First)

As I said, I added the node back into the original xml just as an example.
To load the node into another documnent just change the object:

MyOtherXML.Add(GetNodeForID.First)
Avatar of Victor  Charles

ASKER

Hi,

I'm almost there but still getting an error . I'm using the following Link.xml file

Link.xml:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Root>
  <Link>
   <Link_ID>1</Link_ID>
    <ReceiverID>1</ReceiverID>
    <DonorID>2</DonorID>
  </Link>
  <Link>
    <Link_ID>2</Link_ID>
    <ReceiverID>2</ReceiverID>
    <DonorID>3</DonorID>
  </Link>
 <Link>
    <Link_ID>3</Link_ID>
    <ReceiverID>3</ReceiverID>
    <DonorID>4</DonorID>
 </Link>
<Link>
    <Link_ID>4</Link_ID>
    <ReceiverID>4</ReceiverID>
    <DonorID>5</DonorID>
  </Link>
 <Link>
    <Link_ID>5</Link_ID>
    <ReceiverID>5</ReceiverID>
    <DonorID>1</DonorID>
  </Link>
</Root>

I loaded it in my application with the code below:

Dim MyLink As XDocument = XDocument.Load(Server.MapPath("~/App_Data/Link.xml"))

        Dim XT As XElement =
                <Links>
                    <LinkTemp>
                        <LinkTemp_ID>1</LinkTemp_ID>
                        <Receiver_ID>3</Receiver_ID>
                        <Donor_ID>4</Donor_ID>
                    </LinkTemp>
                    <LinkTemp>
                        <LinkTemp_ID>2</LinkTemp_ID>
                        <Receiver_ID>6</Receiver_ID>
                        <Donor_ID>4</Donor_ID>
                    </LinkTemp>
                    <LinkTemp>
                        <LinkTemp_ID>11</LinkTemp_ID>
                        <Receiver_ID>3</Receiver_ID>
                        <Donor_ID>4</Donor_ID>
                    </LinkTemp>
                </Links>

        Dim ID = 2
        Dim GetNodeForID = From c In XT.Elements("LinkTemp")
                      Where (c.Element("LinkTemp_ID").Value = ID)
                      Select New XElement("Link",
                                          New XElement("Link_ID", ID * 10),
                                          New XElement("Receiver_ID", c.Element("Receiver_ID").Value),
                                          New XElement("Donor_ID", c.Element("Donor_ID").Value))
        MyLink.Add(GetNodeForID.First)

When I press the transfer button, the last record in my Link.xml should be:
 <Link>
       <Link_ID>20</Link_ID>
        <Receiver_ID>6</Receiver_ID>
         <Donor_ID>4</Donor_ID>
  </Link>


But I'm getting error message:
This operation would create an incorrectly structured document.
on line:
MyLink.Add(GetNodeForID.First)


Avatar of MikeToole
MikeToole
Flag of United Kingdom of Great Britain and Northern Ireland image

XT represented the XElement "Links" and the Add() method added to that collection.
MyLink is an XDocument and the statement tries to add a second root element, which triggers the error.
Try:

MyLink.Element("Root").Add(GetNodeForID.First)

This should add the new node to the Root element children.
Avatar of Victor  Charles

ASKER

Hi,
Below is my Link.xml file and latest code, I'm not getting an error but the data did not tranfer to the Link.xml file,
based on XT, the last record should have been:

<Link_ID>20</Link_ID>
<Receiver_ID>6</Receiver_ID>
<Donor_ID>4</Donor_ID>
</Link>


<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Root>
<Link>
<Link_ID>1</Link_ID>
<Receiver_ID>3</Receiver_ID>
<Donor_ID>4</Donor_ID>
</Link>
<Link>
<Link_ID>2</Link_ID>
<Receiver_ID>6</Receiver_ID>
<Donor_ID>4</Donor_ID>
</Link>
<Link>
<Link_ID>11</Link_ID>
<Receiver_ID>3</Receiver_ID>
<Donor_ID>4</Donor_ID>
</Link>
</Root>

Latest Code:

  Dim MyLink As XDocument = XDocument.Load(Server.MapPath("~/App_Data/Link.xml"))

        Dim XT As XElement =
                <Link>
                    <Link>
                        <Link_ID>1</Link_ID>
                        <Receiver_ID>3</Receiver_ID>
                        <Donor_ID>4</Donor_ID>
                    </Link>
                    <Link>
                        <Link_ID>2</Link_ID>
                        <Receiver_ID>6</Receiver_ID>
                        <Donor_ID>4</Donor_ID>
                    </Link>
                    <Link>
                        <Link_ID>11</Link_ID>
                        <Receiver_ID>3</Receiver_ID>
                        <Donor_ID>4</Donor_ID>
                    </Link>
                </Link>

        Dim ID = 2
        Dim GetNodeForID = From c In XT.Elements("Link")
                      Where (c.Element("Link_ID").Value = ID)
                      Select New XElement("Link",
                                          New XElement("Link_ID", ID * 10),
                                          New XElement("Receiver_ID", c.Element("Receiver_ID").Value),
                                          New XElement("Donor_ID", c.Element("Donor_ID").Value))
        MyLink.Element("Root").Add(GetNodeForID.First)
Avatar of MikeToole
MikeToole
Flag of United Kingdom of Great Britain and Northern Ireland image

When I run this code the new node appears at the end of MyLink as expected.
How were you looking at the result? It won't appear in the file unless you save the XDocument :)
This sould do it:
MyLink.Save()

Don't forget to change  New XElement("Link_ID", ID * 10), to New XElement("Link_ID", ID),
The * 10 was just there to generate a different ID
Avatar of Victor  Charles

ASKER

Thanks, I received the follwing error when I include MyLink.save()

Error: Overload  resolution failed because no accessible 'Save' accepts this number of arguments.
Avatar of MikeToole
MikeToole
Flag of United Kingdom of Great Britain and Northern Ireland image

Looking at the Intellisense, you need to give it a file path.
Avatar of Victor  Charles

ASKER

Ok, will get back to yOu later. Thanks.
Avatar of Victor  Charles

ASKER

Thank You!!
ASP.NET
ASP.NET

The successor to Active Server Pages, ASP.NET websites utilize the .NET framework to produce dynamic, data and content-driven web applications and services. ASP.NET code can be written using any .NET supported language. As of 2009, ASP.NET can also apply the Model-View-Controller (MVC) pattern to web applications

128K
Questions
--
Followers
--
Top Experts
Get a personalized solution from industry experts
Ask the experts
Read over 600 more reviews

TRUSTED BY

IBM logoIntel logoMicrosoft logoUbisoft logoSAP logo
Qualcomm logoCitrix Systems logoWorkday logoErnst & Young logo
High performer badgeUsers love us badge
LinkedIn logoFacebook logoX logoInstagram logoTikTok logoYouTube logo