I'm having trouble getting the values of the following XML
<ArrayOf
xmlns="http://schemas.datacontract.org/2004/07/WcfServicePedido_v7"
xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<V>
<D>S</D>
<I>Z</I>
<V>1</V> </V> <V>
<D>S</D>
<I>Z</I>
<V>2</V> </V>
</ArrayOf>
I used to read the following code:
XmlReader xmlReader = XmlReader.Create(url);
XDocument x = XDocument.Load(xmlReader);
var EmpData = from emp in x.Descendants("V")
select new M
{
V = Convert.ToInt32(emp.Descendants("V").First().Value),
I = emp.Descendants("I").First().Value,
D = emp.Descendants("D").First().Value
};
List<M> aux = EmpData.ToList();
I can not get the values. The Empdata is empty.
Your XML has a default namespace.
// untested, from memory
XDocument x = XDocument.Load(xmlReader);
var ns = x.Root.GetDefaultnamespace();
var EmpData = from emp in x.Descendants(ns + "V")
select new M
...
Descendants(ns + "I")
Related
I am trying to parse an xml document with Linq and Lambda expression, but need help.
The Node from within which I want to get data is "DiskDriveInfo" ,
I'm also not sure as to how to proceed with the next node "ResultCode i:nil="true" "
My Code:
var xml = XDocument.Parse(InXML);
var r = from x in xml.Elements("DiskDriveInfo")
select new
{
ResultCode = x.Element("ResultCode").Value,
ResultCodeDescription =
x.Element("ResultCodeDescription").Value,
AirbagDetails = x.Element("AirbagDetails").Value,
..
..
WheelBase = x.Element("WheelBase").Value
};
and the input is :
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">
<s:Body>
<GetConvergedDataRequestResponse xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://autoinsight.trn.co.za/types">
<ConvergedData xmlns:d4p1="http://schemas.datacontract.orgB2B.BusinessModels" i:type="ConvergedResults">
<AccidentHistory i:nil="true" />
<AlertInfo i:nil="true" />
<CloneInfo i:nil="true" />
<DiskDriveInfo>
<ResultCode i:nil="true" />
<ResultCodeDescription i:nil="true" />
<AirbagDetails>DRIVER, PASSENGER</AirbagDetails>
...
...
<WheelBase>2460</WheelBase>
</DiskDriveInfo>
Thx
There are two problems here:
Your elements are in the namespace "http://autoinsight.trn.co.za/types" but you're looking for them without specifying a namespace
You're using xml.Elements which will only look for root elements; to look for any descendants, you should use Descendants.
So you probably want:
XNamespace ns = "http://autoinsight.trn.co.za/types";
var xml = XDocument.Parse(InXML);
var r = from x in xml.Descendants(ns + "DiskDriveInfo")
select new
{
ResultCode = x.Element(ns + "ResultCode").Value,
ResultCodeDescription = x.Element(ns + "ResultCodeDescription").Value,
AirbagDetails = x.Element(ns + "AirbagDetails").Value,
..
..
WheelBase = x.Element(ns + "WheelBase").Value
};
As a side note, I probably wouldn't use a query expression for this - I'd just call Select directly:
var r = xml
.Descendants(ns + "DiskDriveInfo")
.Select(x => new
{
ResultCode = x.Element(ns + "ResultCode").Value,
ResultCodeDescription = x.Element(ns + "ResultCodeDescription").Value,
AirbagDetails = x.Element(ns + "AirbagDetails").Value,
..
..
WheelBase = x.Element(ns + "WheelBase").Value
});
If you need an element with i:nil="true" to return null instead of an empty string, I'd add an extension method for XElement:
private static XNamespace SchemaNamespace = "http://www.w3.org/2001/XMLSchema-instance";
public static string ValueOrNull(this XElement element)
{
XAttribute nil = element.Attribute(SchemaNamespace + "nil");
return (string) nil == "true" ? null : element.Value;
}
Then call it like this:
XNamespace ns = "http://autoinsight.trn.co.za/types";
var xml = XDocument.Parse(InXML);
var r = from x in xml.Descendants(ns + "DiskDriveInfo")
select new
{
ResultCode = x.Element(ns + "ResultCode").ValueOrNull(),
ResultCodeDescription = x.Element(ns + "ResultCodeDescription").ValueOrNull(),
AirbagDetails = x.Element(ns + "AirbagDetails").ValueOrNull(),
..
..
WheelBase = x.Element(ns + "WheelBase").ValueOrNull()
};
You can write from below code just you need to create class according to you xml file and below is function to convert directly xml to class object
public T DeserializeData(string dataXML)
{
XmlDocument xDoc = new XmlDocument();
xDoc.LoadXml(dataXML);
XmlNodeReader xNodeReader = new XmlNodeReader(xDoc.DocumentElement);
XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
var modelData = xmlSerializer.Deserialize(xNodeReader);
T deserializedModel = (T)modelData ;
return deserializedModel;
}
I have an XML looking like this:
<data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<row>
<Alert>warning</Alert>
</row>
</data>
I wan't to get all the rows. In this case, the value that I wan't is "Alert".
This is as fare as I've got...
using (XmlReader reader = cmd.ExecuteXmlReader())
{
string xmlFile = "";
while (reader.Read())
{
xmlFile = reader.ReadOuterXml();
}
var xmlElement = XElement.Parse(xmlFile);
var result = xmlElement.Elements("data").Where(x => x.Value.Equals("row")).ToList();
}
I know something is wrong with my linq, but I'm quite new to linq and would like some help.
Thanks!
XNamespace ns = "http://www.w3.org/2001/XMLSchema-instance";
var xDocument = XDocument.Load("path");
var result = xDocument.Descendants(ns + "row").ToList();
I hope this will work. Please try this.
var xDocument = XDocument.Load(#"XmlFilePath");
//Use below if you have xml in string format
// var xDocument = XDocument.Parse("XmlString");
XNamespace ns = xDocument.Root.GetDefaultNamespace();
var result = xDocument.Descendants(ns + "row").ToList();
<CPT xmlns="http://www.example.org/genericClientProfile" xmlns:ns2="http://www.blahblah.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.example.org/genericClientProfile genericClientProfile.xsd">
<header>
<serviceId>CPT-UK</serviceId>
<versionId>1.0</versionId>
<brandCode>CUK</brandCode>
<creationTime>2013-09-26T13:55:32.31+02:00</creationTime>
</header>
</CPT>
I need to be able to read the elements in the header tag. I'm struggling to read the values for some reason, which i'm not sure of. What i've tried:
public ActionResult readxmldata()
{
using (var db = new CPTEntities())
{
var file = System.IO.Directory.GetFiles("C:\\Workspace\\CPTStaging","*.xml");
foreach (var xmldoc in file)
{
XmlDocument docpath = new XmlDocument();
docpath.Load(xmldoc);
CPTPROFILE doc = new CPTPROFILE();
db.SaveChanges();
H_HEADER header = new H_HEADER();
header.SERVICEID = docpath.SelectSingleNode("//CPT/header/#serviceId").Value;
header.VERSIONID = Convert.ToDecimal(docpath.SelectSingleNode("//CPT/header/#versionId").Value);
header.CREATIONTIME = Convert.ToDateTime(docpath.SelectSingleNode("//CPT/header/#creationTime").Value);
header.BRANDCODE = docpath.SelectSingleNode("//CPT/header/#brandCode").Value;
db.CPTPROFILEs.AddObject(doc);
db.SaveChanges();
}
}
Your XML uses namespaces. xmlns attribute declares default namespace. You should use it for each element of the XML.
XNamespace ns = "http://www.example.org/genericClientProfile";
XDocument doc = XDocument.Load(xmldoc);
XElement header = doc.Root.Element(ns + "header");
For comparison, here is one way to do it with Linq-to-XML:
XDocument doc = XDocument.Load(xmlFileName);
XNamespace ns = "http://www.example.org/genericClientProfile";
var header = doc.Descendants(ns+"header").Single();
H_HEADER header = new H_HEADER();
header.SERVICEID = (string) header.Element(ns + "serviceId");
header.VERSIONID = (double) header.Element(ns + "versionId");
header.BRANDCODE = (string) header.Element(ns + "brandCode");
header.CREATIONTIME = (DateTime) header.Element(ns + "creationTime");
XmlDocument doc = new XmlDocument();
XDocument XMLDoc = XDocument.Load(Path.Combine(Request.PhysicalApplicationPath, "App_Data/google_meta2.xml"));
string id = "2"; // id to be selected
XElement Contact = (from xml2 in XMLDoc.Descendants("Keywords")
where xml2.Element("ID").Value == id
select xml2).FirstOrDefault();
string key = HttpUtility.HtmlDecode(Contact.Element("name").ToString());
/* not works :
string cleanedString = key ;
cleanedString = cleanedString.Replace("<","<"); // No code
cleanedString = cleanedString.Replace(">", ">");
cleanedString = cleanedString.Replace("&", "&"); // No query string breaks
*/
HtmlMeta meta = new HtmlMeta();
meta.Name = "keywords";
meta.Content = key;
MetaPlaceHolder.Controls.Add(meta);
XML
<?xml version="1.0" encoding="utf-8"?>
<Google>
<Keywords>
<ID>2</ID>
<name>bla</name>
</Keywords>
</Google>
Output
<meta name="keywords" content="<name>bla</name>" /></head>
How can i remove the <, or there is better way to do that ?
Try retrieving the attribute from the XElement instead of using HtmlDecode:
XElement contact = (from xml2 in XMLDoc.Descendants("Keywords")
where xml2.Element("ID").Value == id
select xml2).FirstOrDefault();
HtmlMeta meta = new HtmlMeta();
meta.Name = "keywords";
meta.Content = contact.Attribute("name").Value;
I'm working on windows 8 metro apps and i need to get some information from a XML file.
i parse it with LINQ to XML but I've got a problem.
here is the XML:
<feed xmlns="http://www.allocine.net/v6/ns/">
<page>1</page>
<count>1</count>
<results type="movie">10</results>
<results type="person">0</results>
<totalResults>10</totalResults>
<movie code="61282">
<originalTitle>Avatar</originalTitle>
<title>Avatar</title>
<productionYear>2009</productionYear>
<release>
<releaseDate>2010-09-01</releaseDate>
</release>
<castingShort>
<directors>James Cameron</directors>
<actors>Sam Worthington, Zoe Saldana, Sigourney Weaver, Stephen Lang, Michelle Rodriguez</actors>
</castingShort>
<statistics>
<pressRating>4.33333</pressRating>
<userRating>4.31338</userRating>
</statistics>
<poster path="/medias/nmedia/18/78/95/70/19485155.jpg"
href="http://images.allocine.fr/medias/nmedia/18/78/95/70/19485155.jpg"/>
<linkList>
<link rel="aco:web"
href="http://www.allocine.fr/film/fichefilm_gen_cfilm=61282.html"/>
</linkList>
</movie>
</feed>
I need to get "code" value of the "movie" node and the "href" value of the node "link" but all the things i tried failed ...
You can consider that the beginning of the XML is <movie> because I get the file and i parse it to keep the XML clean as I want. my file start with <movie code="">
For a classic value like "actors" i do :
Actors = (string)query.Element("castingShort").Element("actors")
It is working perfectly! My problem is for the specific value with a name.
edit :
that's what i did with your advices.
var group1 = new SampleDataGroup("Group-1", "Films", "", "Assets/icone_groupe_all_movies.jpg", "Films sur le DD");
movieName = "avatar";
Uri = "http://api.allocine.fr/rest/v3/search?partner=YW5kcm9pZC12M3M&filter=movie,person&count=1&page=1&q=" + movieName + "&format=xml";
var httpResponse = await new HttpClient().GetAsync(Uri);
string sourceCode = get_new_xml(await httpResponse.Content.ReadAsStringAsync());
XDocument doc = XDocument.Parse(sourceCode);
XNamespace ns = "http://www.allocine.net/v6/ns/";
XElement movie = doc.Root.Element(ns + "movie");
XElement castingShort = movie.Element(ns + "castingShort");
XElement statistics = movie.Element(ns + "statistics");
Data data = new Data
{
MovieCode = (string)movie.Attribute("code"),
OriginalTitle = (string)movie.Element(ns + "originalTitle"),
Title = (string)movie.Element(ns + "title"),
ProductionYear = (string)movie.Element(ns + "productionYear"),
Directors = (string)castingShort.Element(ns + "directors"),
Actors = (string)castingShort.Element(ns + "actors"),
PressRating = (string)statistics.Element(ns + "pressRating"),
UserRating = (string)statistics.Element(ns + "userRating"),
Cover = (string)movie.Element(ns + "linkList").Element(ns + "link").Attribute("href")
};
group1.Items.Add(new SampleDataItem("Group-1-Item-1", data.Title, data.Cover, data.ProductionYear, "", data.ReleaseDate, group1));
this.AllGroups.Add(group1);
but unfortunately it still doesent work ...
Thus you have namespace declared in your xml, you should declare and initialize an XNamespace object, and to use it when specifying XName objects (arguments to Element methods):
XDocument xdoc = XDocument.Load(path_to_xml);
XNamespace ns = "http://www.allocine.net/v6/ns/";
XElement movie = xdoc.Root.Element(ns + "movie");
var code = (int)movie.Attribute("code");
var href = (string)movie.Element(ns + "linkList")
.Element(ns + "link").Attribute("href");
If you have only one <movie> element, then you don't need to operate on sequence of movie elements and treat single movie as list. Simply get movie node and create new data object via parsing that node:
XNamespace ns = "http://www.allocine.net/v6/ns/";
XElement movie = xdoc.Root.Element(ns + "movie");
XElement castingShort = movie.Element(ns + "castingShort");
XElement statistics = movie.Element(ns + "statistics");
Data data = new Data
{
MovieCode = (int)movie.Attribute("code"),
OriginalTitle = (string)movie.Element(ns + "originalTitle"),
Title = (string)movie.Element(ns + "title"),
ProductionYear = (string)movie.Element(ns + "productionYear"),
Directors = (string)castingShort.Element(ns + "directors"),
Actors = (string)castingShort.Element(ns + "actors"),
PressRating = (string)statistics.Element(ns + "pressRating"),
UserRating = (string)statistics.Element(ns + "userRating"),
Cover = (string)movie.Element(ns + "linkList")
.Element(ns + "link").Attribute("href")
};