Linq to XML programming
-
Hi there, I'm trying to teach myself linq to xml and I've been struggling to implement a linq to xml class with which I can update values in a given xml file. I'm a total beginner at this so I have probably made a simple mistake. My Base class is as follows:
Public Class WebSite
Private _Id As String
Public Property Id() As String
Get
Return (_Id)
End Get
Set(ByVal value As String)
_Id = value
End Set
End Property
Private _Link As String
Public Property Link() As String
Get
Return (_Link)
End Get
Set(ByVal value As String)
_Link = value
End Set
End PropertyPrivate \_Picture As String Public Property Picture() As String Get Return (\_Picture) End Get Set(ByVal value As String) \_Picture = value End Set End Property Private \_ModifiedOn As String Public Property ModifiedOn() As String Get Return (\_ModifiedOn) End Get Set(ByVal value As String) \_ModifiedOn = value End Set End Property Public Sub New(ByVal xElement As XElement) Id = xElement.Attribute("Id").Value Link = xElement.Element("Link").Value Picture = xElement.Element("Picture").Value ModifiedOn = xElement.Element("ModifiedOn").Value End Sub Private \_xElement As XElement Public Property xElement() As XElement Get Return New XElement("Website", New XAttribute("Id", Id), New XElement("Link", Link), New XElement("Picture", Picture), New XElement("ModifiedOn", ModifiedOn)) End Get Set(ByVal value As XElement) \_xElement = value End Set End Property
The sub that I am trying to implement is as follows:
Public Class Portfolio
Inherits List(Of WebSite)Public Sub UpdateWebsite(ByVal xmlFile As String, ByVal WebId As String, ByVal WebLink As String, ByVal WebPic As String, ByVal WebMod As String) Dim doc As XDocument = XDocument.Load(xmlFile) Dim query = From xElem In doc.Descendants("Website") \_ Where xElem.@Id = WebId \_ Select New WebSite(xElem) With query.SingleOrDefault .Id = WebId .Link = WebLink .Picture = WebPic .ModifiedOn = WebMod End With Me.Clear()
-
Hi there, I'm trying to teach myself linq to xml and I've been struggling to implement a linq to xml class with which I can update values in a given xml file. I'm a total beginner at this so I have probably made a simple mistake. My Base class is as follows:
Public Class WebSite
Private _Id As String
Public Property Id() As String
Get
Return (_Id)
End Get
Set(ByVal value As String)
_Id = value
End Set
End Property
Private _Link As String
Public Property Link() As String
Get
Return (_Link)
End Get
Set(ByVal value As String)
_Link = value
End Set
End PropertyPrivate \_Picture As String Public Property Picture() As String Get Return (\_Picture) End Get Set(ByVal value As String) \_Picture = value End Set End Property Private \_ModifiedOn As String Public Property ModifiedOn() As String Get Return (\_ModifiedOn) End Get Set(ByVal value As String) \_ModifiedOn = value End Set End Property Public Sub New(ByVal xElement As XElement) Id = xElement.Attribute("Id").Value Link = xElement.Element("Link").Value Picture = xElement.Element("Picture").Value ModifiedOn = xElement.Element("ModifiedOn").Value End Sub Private \_xElement As XElement Public Property xElement() As XElement Get Return New XElement("Website", New XAttribute("Id", Id), New XElement("Link", Link), New XElement("Picture", Picture), New XElement("ModifiedOn", ModifiedOn)) End Get Set(ByVal value As XElement) \_xElement = value End Set End Property
The sub that I am trying to implement is as follows:
Public Class Portfolio
Inherits List(Of WebSite)Public Sub UpdateWebsite(ByVal xmlFile As String, ByVal WebId As String, ByVal WebLink As String, ByVal WebPic As String, ByVal WebMod As String) Dim doc As XDocument = XDocument.Load(xmlFile) Dim query = From xElem In doc.Descendants("Website") \_ Where xElem.@Id = WebId \_ Select New WebSite(xElem) With query.SingleOrDefault .Id = WebId .Link = WebLink .Picture = WebPic .ModifiedOn = WebMod End With Me.Clear()
JimBob SquarePants wrote:
With query.SingleOrDefault
.Id = WebId
.Link = WebLink
.Picture = WebPic
.ModifiedOn = WebMod
End WithMe.Clear()
AddRange(query)Save(xmlFile)
This is your problem. The query will be enumerated once to get the SingleOrDefault. The returned item will be modified and then thrown away at the End With. The query will be enumerated again (making a new set of Websites) when you call AddRange.
-
JimBob SquarePants wrote:
With query.SingleOrDefault
.Id = WebId
.Link = WebLink
.Picture = WebPic
.ModifiedOn = WebMod
End WithMe.Clear()
AddRange(query)Save(xmlFile)
This is your problem. The query will be enumerated once to get the SingleOrDefault. The returned item will be modified and then thrown away at the End With. The query will be enumerated again (making a new set of Websites) when you call AddRange.
So what do you suggest? When I debug the code I can see that none of the values are being updated even before I reach the end of the with. I just cant figure it out? Many Thanks
JimBob SquarePants ******************************************************************* "He took everything personally, including our royalties!" David St.Hubbins, Spinal Tap about Ian Faith, their ex-manager *******************************************************************
-
So what do you suggest? When I debug the code I can see that none of the values are being updated even before I reach the end of the with. I just cant figure it out? Many Thanks
JimBob SquarePants ******************************************************************* "He took everything personally, including our royalties!" David St.Hubbins, Spinal Tap about Ian Faith, their ex-manager *******************************************************************
Hey dude, I followed this here from the cross post reply. I can't help you with linq because I have never used it, yet. Not sure when I will start but it seems inevitable. However since you said you were still stuck I can speak to being a beginner and stuck since I of course was there often myself. One suggestion is to abandon your specific goal for now and go back to just studying LINQ. What I find is doing so will almost always result in gaining an understanding of the technology and ultimately I am able to return to the original task and solve the problem.
-
So what do you suggest? When I debug the code I can see that none of the values are being updated even before I reach the end of the with. I just cant figure it out? Many Thanks
JimBob SquarePants ******************************************************************* "He took everything personally, including our royalties!" David St.Hubbins, Spinal Tap about Ian Faith, their ex-manager *******************************************************************
How exactly are you checking the values as you debug? If you are adding "query.SingleOrDefault" to the watch window, then it will reenumerate the collection every time you refresh it in the debug window, thus giving you the original data. I would suggest having a Load method that loads the files into the list and have the UpdateWebsite method find the matching website from the loaded sites. Also, you are using VB, so you should take advantage of the XML literals and XLinq syntax. You could change the WebSite constructor and xElement property getter to look like this:
Public Sub New(ByVal xElement As XElement)
Id = xElement.@Id
Link = xElement.<Link>.Value
Picture = xElement.<Picture>.Value
ModifiedOn = xElement.<ModifiedOn>.Value
End Sub
Private _xElement As XElement
Public Property xElement() As XElement
Get
Return <Website Id=<%= Me.Id %>>
<Link><%= Me.Link %></Link>
<Picture><%= Me.Picture %></Picture>
<ModifiedOn><%= Me.ModifiedOn %></ModifiedOn>
</Website>
End Get
Set(ByVal value As XElement)
_xElement = value
End Set
End Property -
How exactly are you checking the values as you debug? If you are adding "query.SingleOrDefault" to the watch window, then it will reenumerate the collection every time you refresh it in the debug window, thus giving you the original data. I would suggest having a Load method that loads the files into the list and have the UpdateWebsite method find the matching website from the loaded sites. Also, you are using VB, so you should take advantage of the XML literals and XLinq syntax. You could change the WebSite constructor and xElement property getter to look like this:
Public Sub New(ByVal xElement As XElement)
Id = xElement.@Id
Link = xElement.<Link>.Value
Picture = xElement.<Picture>.Value
ModifiedOn = xElement.<ModifiedOn>.Value
End Sub
Private _xElement As XElement
Public Property xElement() As XElement
Get
Return <Website Id=<%= Me.Id %>>
<Link><%= Me.Link %></Link>
<Picture><%= Me.Picture %></Picture>
<ModifiedOn><%= Me.ModifiedOn %></ModifiedOn>
</Website>
End Get
Set(ByVal value As XElement)
_xElement = value
End Set
End PropertyThanks for your help! There always seems so be so many ways to solve a problem when programming, I fear for the sanity of anyone who does this professionally. I followed led mikes advice and did a bit more studying and I seem to have cracked it. Just built a fully funtional content management website with membership et al in just over 20 hours! feeling quite pleased with myself. I can definitely see the benefits of using xml for smaller traffic sites rather than a database. I'll have a good look at your code and see i can learn more. I'm really starting to get into all this. Many thanks James
JimBob SquarePants ******************************************************************* "He took everything personally, including our royalties!" David St.Hubbins, Spinal Tap about Ian Faith, their ex-manager *******************************************************************
-
Hey dude, I followed this here from the cross post reply. I can't help you with linq because I have never used it, yet. Not sure when I will start but it seems inevitable. However since you said you were still stuck I can speak to being a beginner and stuck since I of course was there often myself. One suggestion is to abandon your specific goal for now and go back to just studying LINQ. What I find is doing so will almost always result in gaining an understanding of the technology and ultimately I am able to return to the original task and solve the problem.
Hopefully you'll read this. Thanks for your input. I followed your advice and started studying again with great success. I figured out all my problems and solved a few new ones one the way. I looked at linq first cos quie frankly the whole ado.net thing scares me. It seems for the most part to make pretty good sense. I'm looking forward to learning more. Thanks again James
JimBob SquarePants ******************************************************************* "He took everything personally, including our royalties!" David St.Hubbins, Spinal Tap about Ian Faith, their ex-manager *******************************************************************
-
Hopefully you'll read this. Thanks for your input. I followed your advice and started studying again with great success. I figured out all my problems and solved a few new ones one the way. I looked at linq first cos quie frankly the whole ado.net thing scares me. It seems for the most part to make pretty good sense. I'm looking forward to learning more. Thanks again James
JimBob SquarePants ******************************************************************* "He took everything personally, including our royalties!" David St.Hubbins, Spinal Tap about Ian Faith, their ex-manager *******************************************************************