Error when get data from xml file - c#

I have profile.xml file in my web folder:
<?xml version="1.0" encoding="utf-8"?>
<myXML>
<RealName>Nguyen Van A</RealName>
<Email>vyclarks#gmail.com</Email>
<Phone>2165421</Phone>
<Address>Ho Chi Minh</Address>
<Link1>dtvt</Link1>
<Link2></Link2>
<Link3></Link3>
</myXML>
As recommended, I get data from that file by code below:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Xml.Linq;
public class profile
{
public string realname { get; set; }
public string email { get; set; }
public string phone { get; set; }
public string address { get; set; }
public string link1 { get; set; }
public string link2 { get; set; }
public string link3 { get; set; }
}
public void getProfile()
{
string path = this.Server.MapPath("~/Lecturer/");
string targetPath = path + #"\"+username+"\\profile.xml";
bool isExists = System.IO.Directory.Exists(targetPath);
if(isExists)
{
List<profile> profiles = (
from e in XDocument.Load(targetPath)
.Root.Element("myXML")
select new profile
{
realname = (string) e.Element("RealName"),
email = (string) e.Element("Email"),
phone = (string) e.Element("Phone"),
address = (string) e.Element("Address"),
link1 = (string) e.Element("Link1"),
link2 = (string) e.Element("Link2"),
link3 = (string) e.Element("Link3")
}
).ToList();
}
...//code to get list value...
}
But it has an error: Cannot resolve symbol "select"
Is there any better way to get data from profile.xml file???

There is an error in your from e in ... statement.
XDocument.Load(targetPath).Root.Element("myXML") returns only one XML element for you. So you can't do linq query against a single object (don't mix with the collections containing only one object).
To get it working you need to change Element method to Elements:
from e in XDocument.Load(targetPath).Root.Elements("myXML")
select new profile
{
realname = (string) e.Element("RealName"),
email = (string) e.Element("Email"),
phone = (string) e.Element("Phone"),
address = (string) e.Element("Address"),
link1 = (string) e.Element("Link1"),
link2 = (string) e.Element("Link2"),
link3 = (string) e.Element("Link3")
}
Update
If you have only one myXML node in XML file (since it's a root node in your example) then you don't need linq query at all. Try to read data from the XML in a next way:
var prof = XDocument.Load(targetPath).Root;
var p = new profile()
{
realname = prof.Element("RealName").Value,
email = prof.Element("Email").Value,
phone = prof.Element("Phone").Value,
address = prof.Element("Address").Value,
link1 = prof.Element("Link1").Value,
link2 = prof.Element("Link2").Value,
link3 = prof.Element("Link3").Value
}
I've tested it with XML from your sample

Related

C# and LINQ.XML Select from XML

I've been struggling to find out how to select multiple values from an XML file, compare them to a special value and then do something. So far I just managed to select a single value but I also need a different one in the same select, I hope you can assist me
XML Structure
<?xml version="1.0" encoding="utf-8"?>
<userConnectionSettings version="1" lastApplicationUrl="xxx" lastIdentity="yyy">
<application url="xxx" lastFolderId="zzz">
<user name="test" domain="domain.tld" lastFolderId="yyy" />
</application>
</userConnectionSettings>
Now basically, what i want to do is read the lastApplicationURL and the domain value. I managed to do the lastApplicationURL but i can't seem to select the domain and i don't know how to get that value properly. Here's my code :
XDocument foDoc = XDocument.Load(FrontOfficePath);
foreach (var FOurl in foDoc.Descendants("userConnectionSettings"))
{
string FOappURL = (string)FOurl.Attribute("lastApplicationUrl");
if (FOappURL == "something")
{
TODO
}
else
{
TODO
}
}
You can select domain attribute, in two different ways :
1 - Like #Juharr comment :
foreach (var FOurl in foDoc.Descendants("userConnectionSettings"))
{
string domain = FOurl
.Element("application")
.Element("user")
.Attribute("domain")
.Value;
....
}
Or, by getting descendant of application and select the first item, like :
foreach (var FOurl in foDoc.Descendants("userConnectionSettings"))
{
string domain = FOurl.Descendants("application")
.Select(x => x.Element("user").Attribute("domain").Value)
.FirstOrDefault();
....
}
i hope you find this helpful.
Try following :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
List<Application> applications = doc.Descendants("application").Select(x => new Application()
{
url = (string)x.Attribute("url"),
id = (string)x.Attribute("lastFolderId"),
name = (string)x.Element("user").Attribute("name"),
domain = (string)x.Element("user").Attribute("domain"),
folder = (string)x.Element("user").Attribute("lastFolderId")
}).ToList();
}
}
public class Application
{
public string url { get; set; }
public string id { get; set; }
public string name { get; set; }
public string domain { get; set; }
public string folder { get; set; }
}
}

Read from XML Using Linq and add it to a list containing objects

I'm trying to read from an XML file and add every contact to the contacts list the error i get is that can't convert List to List
writes an xml file for each contact in contacts (Works)
var path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
var xEle = new XElement("Contact",
from contact in contacts
select new XElement("Contact",
new XAttribute("Name", contact.Name),
new XElement("Address", contact.StreetAddress),
new XElement("AreaCode", contact.AreaCode),
new XElement("City", contact.City),
new XElement("Phone", contact.Phone),
new XElement("Email", contact.Email)
));
xEle.Save(path + "\\contacts.xml");
Reads from the xml and adds it to the list (DOES NOT WORK!)
XDocument xmlDoc = XDocument.Load(path + "\\contacts.xml");
contacts = (List<Contact>)xmlDoc.Descendants("Contact");
XML File Output
<Contacts>
<Contact Name="Nils Nilsson">
<Address>MyStreet 17B</Address>
<AreaCode>55555</AreaCode>
<City>BigCity</City>
<Phone>0705555555</Phone>
<Email>mail#gmail.com</Email>
</Contact>
</Contact>
Contact Class
public class Contact
{
public string Name { get; set; }
public string StreetAddress { get; set; }
public string AreaCode { get; set; }
public string City { get; set; }
public string Phone { get; set; }
public string Email { get; set; }
}
My existing list
List<Contact> contacts = new List<Contact>();
As pointed out, the reason your original code doesn't work is that all queries in LINQ to XML return some form of XObject - most commonly an XAttribute or XElement. It won't map anything to Contact.
The easiest way to map your XML to your objects is to make use of built in support for XML Serialization. You class needs a couple of attributes & an extra class to map to your XML structure:
[XmlRoot("Contacts")]
public class Contacts : List<Contact>
{
}
public class Contact
{
[XmlAttribute]
public string Name { get; set; }
[XmlElement("Address")]
public string StreetAddress { get; set; }
public string AreaCode { get; set; }
public string City { get; set; }
public string Phone { get; set; }
public string Email { get; set; }
}
And then read your XML as follows:
using (var reader = XmlReader.Create(Path.Combine(path, "contacts.xml"))
{
var serializer = new XmlSerializer(typeof(Contacts));
var contacts = (Contacts)serializer.Deserialize(reader);
}
Note you can also use the Serialize method to create the XML in the first instance.
You can try something like this:
var xmlDoc = XDocument.Load(path + "\\contacts.xml");
var xElements = xmlDoc.Descendants("Contact");
var xmlSerializer = new XmlSerializer(typeof(Contact));
contacts = xElements.Select(xe => (Contact)xmlSerializer.Deserialize(xe.CreateReader())).ToList();

List.count=0 when get data from XML file to List()

I'm having an user.xml file like:
<?xml version="1.0" encoding="utf-8"?>
<myXML>
<RealName>Nguyen Van A</RealName>
<Email>vyclarks#gmail.com</Email>
<Phone>2165421</Phone>
<Address>Ho Chi Minh</Address>
<Link1>dtvt</Link1>
<Link2></Link2>
<Link3></Link3>
</myXML>
and I have code to get data from xml file:
public class user
{
public string realname { get; set; }
public string email { get; set; }
public string phone { get; set; }
public string address { get; set; }
public string link1 { get; set; }
public string link2 { get; set; }
public string link3 { get; set; }
}
public void getUser()
{
List<user> us = (
from e in
XDocument.Load("user.xml").Root.Elements("myXML")
select new user
{
realname = (string)e.Element("RealName"),
email = (string)e.Element("Email"),
phone = (string)e.Element("Phone"),
address = (string)e.Element("Address"),
link1 = (string)e.Element("Link1"),
link2 = (string)e.Element("Link2"),
link3 = (string)e.Element("Link3")
}
).ToList();
//get data from list to label
lblrealname.Text = us[0].ToString();
lblmail.Text = us[1].ToString();
lblphone.Text = us[2].ToString();
lbladd.Text = us[3].ToString();
lbllink1.Text = us[4].ToString();
lbllink2.Text = us[5].ToString();
lbllink3.Text = us[6].ToString();
}
But when I built, it has an error in line:lblrealname.Text = profiles[0].ToString(); this is the content: Index was out of range. Must be non-negative and less than the size of the collection.
Then I debug, the us.count = 0 ---> I wonder if that my code above has some mistakes so there no item in list us.
Help!! I cannot find where is wrong and is there any better way to get data from that xml file.
Split UI and Data Access logic. Make your method return User object instead of being void. Thus there is only one root in your xml, you don't need to write query which returns list of users - simply access root node directly. Also use PascalCase for type names, methods and properties:
public User GetUser()
{
var root = XDocument.Load("user.xml").Root;
return new User {
RealName = (string)root.Element("RealName"),
Email = (string)root.Element("Email"),
Phone = (string)root.Element("Phone"),
Address = (string)root.Element("Address"),
Link1 = (string)root.Element("Link1"),
Link2 = (string)root.Element("Link2"),
Link3 = (string)root.Element("Link3")
};
}
Displaying user on UI:
public void DisplayUser(User user)
{
lblrealname.Text = user.RealName;
lblmail.Text = user.Email;
lblphone.Text = user.Phone;
lbladd.Text = user.Address;
lbllink1.Text = user.Link1;
lbllink2.Text = user.Link2;
lbllink3.Text = user.Link3;
}
And all together:
var user = GetUser();
DispalylUser(user);
The following line
from e in XDocument.Load("user.xml").Root.Elements("myXML")
results in 0 results because <myXML> is the root, and it doesn't look like it contains any nested <myXML> within it.
The following should work.
from e in XDocument.Load("user.xml").Elements("myXML")
and if you don't need an enumerable, you can just take the root
var element = XDocument.Load("user.xml").Root;

How to loop through a set of XElements?

http://www.dreamincode.net/forums/xml.php?showuser=335389
Given the XML above, how can I iterate through each element inside of the 'lastvisitors' element, given that each child group is the same with just different values?
//Load latest visitors.
var visitorXML = xml.Element("ipb").Element("profile").Element("latestvisitors");
So now I have captured the XElement containing everything I need. Is there a way to loop through the elements to get what I need?
I have this POCO object called Visitor whose only purpose is to hold the necesary information.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SharpDIC.Entities
{
public class Visitor
{
public string ID { get; set; }
public string Name { get; set; }
public string Url { get; set; }
public string Photo { get; set; }
public string Visited { get; set; }
}
}
Thanks again for the help.
You can probably just do something like this in Linq:
XDocument xml = XDocument.Parse(xmlString);
var visitors = (from visitor in xml.Descendants("latestvisitors").Descendants("user")
select new Visitor() {
ID = visitor.Element("id").Value,
Name = visitor.Element("name").Value,
Url = visitor.Element("url").Value,
Photo = visitor.Element("photo").Value,
Visited = visitor.Element("visited").Value
});
The only caveat here is that I didn't do any null checking.
Just do a linq query to select all the elements as your object.
var visitors = (from v in xml.Element("ipb").Element("profile")
.Element("latestvisitors").Elements()
select new Visitor {
ID = (string)v.Element("id"),
Name = (string)v.Element("name"),
}).ToList();

LINQ XML Read different hierarchies into 1 object

I have an XML file
<searchResponse requestID=“500” status=“success”>
<pso>
<psoID ID=“770e8400-e29b-41d4-a716-446655448549”
targetID=“mezeoAccount”/>
<data>
<email>user2#example.net</email>
<quotaMeg>100</quotaMeg>
<quotaUsed>23</quotaUsed>
<realm>Mezeo</realm>
<path>/san1/</path>
<billing>user2</billing>
<active>true</active>
<unlocked>true</unlocked>
<allowPublic>true</allowPublic>
<bandwidthQuota>1000000000</bandwidthQuota>
<billingDay>1</billingDay>
</data>
</pso>
</searchRequest>
and I want to extract the data into a single business object. Am I better to go
MezeoAccount mcspAccount = new MezeoAccount();
mcspAccount.PsoID = doc.Element("psoID").Attribute("ID").Value;
mcspAccount.Email = doc.Element("email").Value;
...
or build a list even though I know there is only 1 record in the file?
var psoQuery = from pso in doc.Descendants("data")
select new MezeoAccount {
PsoID = pso.Parent.Element("psoID").Attribute("ID").Value,
Email = pso.Element("email").Value,
... };
What would people suggest would be the more correct way, or a better way even, if I missed something.
If you know that your xml only will contain one record of the data in mind you shouldn't create a list for it. So your first example looks fine.
A pattern I personally use is something like this:
public class MezeoAccount
{
public string PsoID { get; set; }
public string Email { get; set; }
public static MezeoAccount CreateFromXml(XmlDocument xml)
{
return new MezeoAccount()
{
PsoID = xml.Element("psoID").Attribute("ID").Value,
Email = doc.Element("email").Value;
};
}
}
//Usage
var mezeoAccount = MezeoAccount.CreateFromXml(xml);
It looks like you didn't get a working answer to this question. Assuming that there can only be one account in the XML file, I would do it like this:
using System;
using System.Linq;
using System.Xml.Linq;
public class MezeoAccount
{
public string PsoId { get; set; }
public string Email { get; set; }
public int QuotaMeg { get; set; }
// Other properties...
}
public class Program
{
public static void Main()
{
XDocument doc = XDocument.Load("input.xml");
XElement pso = doc.Element("searchResponse").Element("pso");
XElement data = pso.Element("data");
MezeoAccount x = new MezeoAccount
{
PsoId = pso.Element("psoID").Attribute("ID").Value,
Email = data.Element("email").Value,
QuotaMeg = int.Parse(data.Element("quotaMeg").Value),
// Other properties...
};
}
}

Categories