LINQ to XML: How to get element value in C#? - c#

I have this XML structure:
<?xml version="1.0" encoding="utf-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope">
<SOAP-ENV:Header>
<dlv:delivery xmlns:dlv="http://schemas.biztalk.org/btf-2-0/delivery">
<dlv:message>
<dlv:messageID>SDID20200921053955</dlv:messageID>
<dlv:sent>2020-09-21T05:39:55</dlv:sent>
</dlv:message>
<dlv:to>
<dlv:address>urn:schindler:SchindlerDraw:prod</dlv:address>
</dlv:to>
<dlv:from>
<dlv:address>urn:schindler:logical-system:CRM</dlv:address>
</dlv:from>
<dlv:from>
<dlv:system>PC1</dlv:system>
</dlv:from>
</dlv:delivery>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
<asx:values>
<SALESORDER>
<EXTENSIONIN>
<item>
<CONFIRMATIONPRINTDATE />
<CUSTOMEROFFERNOTE />
<CUSTOMERREFERENCE />
</item>
</EXTENSIONIN>
</SALESORDER>
</asx:values>
</asx:abap>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Does anyone know how I can get all the values from the element "item"?
The result should be:
CONFIRMATIONPRINTDATE
CUSTOMEROFFERNOT
CUSTOMERREFERENCE
Thank you in advance.

Use xml linq :
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);
XElement delivery = doc.Descendants().Where(x => x.Name.LocalName == "delivery").FirstOrDefault();
XNamespace dlv = delivery.GetNamespaceOfPrefix("dlv");
Envelope envelope = new Envelope();
envelope.messageId = (string)delivery.Descendants(dlv + "messageID").FirstOrDefault();
envelope.sent = (DateTime)delivery.Descendants(dlv + "sent").FirstOrDefault();
envelope.toAddr = (string)delivery.Descendants(dlv + "from").FirstOrDefault().Element(dlv + "address");
envelope.fromAddr = (string)delivery.Descendants(dlv + "to").FirstOrDefault().Element(dlv + "address");
envelope.system = (string)delivery.Descendants(dlv + "system").FirstOrDefault();
envelope.items = doc.Descendants("item").FirstOrDefault().Elements()
.GroupBy(x => x.Name.LocalName, y => (string)y)
.ToDictionary(x => x.Key, y => y.FirstOrDefault());
}
}
public class Envelope
{
public string messageId { get; set; }
public DateTime sent { get; set; }
public string toAddr { get; set; }
public string fromAddr { get; set; }
public string system { get; set; }
public Dictionary<string,string> items { get; set; }
}
}

Related

How to read data from soap service c#

I am creating a .net core web api method to get the data from xml file based on request. The data is from soap service. Below is request Parameter. So i am searching based on the request parameter.(producer code)
Request------>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:get="http://xyz/business/profile_management_ebe4x1">
<soapenv:Header/>
<soapenv:Body>
<get:GetProducerInfo>
<!--Optional:-->
<GetProducerInfoRequest>
<ProducerCode>IT9559</ProducerCode>
</GetProducerInfoRequest>
</get:GetProducerInfo>
</soapenv:Body>
</soapenv:Envelope>
Below is the response i am looking
Response------->
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<dlwmin:GetProducerInfoResponse xmlns:dlwmin="http://xyz/business/Profile_management_ebe4x1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<GetProducerInfoReply xmlns:ns2="http://xyz/get_access/producer_info" xmlns:ns3="http://yzy/business/profile_reply_ebe4x1">
<Producer>
<ProducerName>MARSH & ABC company</ProducerName>
<ResidentState>TEXAS</ResidentState>
<ResidentCity>MIDLAND</ResidentCity>
<ProducerStatus>Open</ProducerStatus>
<ProducerCode>IT6372</ProducerCode>
<MasterCode>272495</MasterCode>
<NationalCode>174144</NationalCode>
<ProducingBranchCode>ABO</ProducingBranchCode>
<CategoryCode>INT</CategoryCode>
</Producer>
<Producer>
<ProducerName>MARSH & ABC company </ProducerName>
<ResidentState>MICHIGAN</ResidentState>
<ResidentCity>LIVONIA</ResidentCity>
<ProducerStatus>Open</ProducerStatus>
<ProducerCode>IT9559</ProducerCode>
<MasterCode>IT9559</MasterCode>
<NationalCode>174144</NationalCode>
<LegacyCode>0036604-99999</LegacyCode>
<ProducingBranchCode>MBO</ProducingBranchCode>
<CategoryCode>GEN</CategoryCode>
</Producer>
I have created xml file in .net solution
XDocument xdoc = XDocument.Load(Path.Combine(Directory.GetCurrentDirectory(), "ProducerResponse.xml"));
XNamespace ns = "http://xyz/get_access/producer_info";
how i can start read from producer node on request.<producer> always does not not contain equal data. some time it contains 9 or 10. data as it looking from the above data.
TIA
Try xml linq :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
//put response string here
string response = File.ReadAllText(FILENAME);
XDocument doc = XDocument.Parse(response);
List<Producer> producers = doc.Descendants("Producer").Select(x => new Producer()
{
ProducerName = (string)x.Element("ProducerName"),
ResidentState = (string)x.Element("ResidentState"),
ResidentCity = (string)x.Element("ResidentCity"),
ProducerStatus = (string)x.Element("ProducerStatus"),
ProducerCode = (string)x.Element("ProducerCode"),
MasterCode = (string)x.Element("MasterCode"),
NationalCode = (string)x.Element("NationalCode"),
LegacyCode = (string)x.Element("LegacyCode"),
ProducingBranchCode = (string)x.Element("ProducingBranchCode"),
CategoryCode = (string)x.Element("CategoryCode")
}).ToList();
Dictionary<string, Producer> dict1 = producers
.GroupBy(x => x.ProducerCode, y => y)
.ToDictionary(x => x.Key, y => y.FirstOrDefault());
Dictionary<string, List<Producer>> dict2 = producers
.GroupBy(x => x.ProducerCode, y => y)
.ToDictionary(x => x.Key, y => y.ToList());
}
}
public class Producer
{
public string ProducerName { get; set; }
public string ResidentState { get; set; }
public string ResidentCity { get; set; }
public string ProducerStatus { get; set; }
public string ProducerCode { get; set; }
public string MasterCode { get; set; }
public string NationalCode { get; set; }
public string LegacyCode { get; set; }
public string ProducingBranchCode { get; set; }
public string CategoryCode { get; set; }
}
}

Complex XML to C# classes - how to deserialize them?

My goal is to extract the data from the XML. But I have some rather complex XML that is not easily converted to C sharp classes.
The XML looks like this:
<group.........>
<suite....>
<properties>
<property name=....../>
</properties>
<suite type="test">
<suite type="test1">
<suite...>
<suite...>
<suite...>
<case id="1000" name="example">
<properties>
<property ...../>
</properties>
</case>
<case.......>
<properties>
<property ...../>
</properties>
</case>
<case>
<properties>
<property .... />
</properties>
</case>
</suite>
</suite>
</suite>
</suite>
</suite>
</suite>
</group>
I have used an online xml to c sharp convert to create classes, but it does not seem to handle the XML structure correctly.
Update:
The XML comes from NUNIT3. It is the result of the UNIT3 console that is written to an XML document.
Update 2:
I am able to extract data using below code - don't know if there is a more elegant solution:
XElement resultFile = XElement.Load($"{resultFilePathList}");
var dataFromXML = (
from data in resultFile.Descendants("case")
select new
{
caseid = data.Attribute("id").Value,
name = data.Attribute("fullname").Value,
result = data.Attribute("result").Value,
duration = data.Attribute("duration").Value
}
);
Check this code, is as simple as this
using System.Xml.Serialization;
using System.IO;
.......
StreamReader streamer = new StreamReader("yourgroup.xml");
XmlSerializer serializer = new XmlSerializer(typeof(group));
group x = (group)serializer.Deserialize(streamer);
streamer.Close();
And you have do define your classes, somehow like this
public class group {List<suite> suite;}
public class suite
{
public List<suite> suite;
public List<property> properties;
}
Ok, you can add additional annotation if you need specific handling
For instance if there is "case" element, create your class with different name
public class xcase
{
public String id;
public String name;
public Property[] properties;...
}
public class suite
{
[XmlElement(ElementName = "case")]
public xcase[] cases {get; set; }
....
}
Try following :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication120
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
XElement group = doc.Root;
Suite rootSuite = new Suite();
Suite.ReadXml(group, rootSuite);
}
}
public class Suite
{
public List<Suite> suites { get; set; }
public List<Case> cases { get; set; }
public Dictionary<string, string> properties { get; set; }
public string type { get; set; }
public static void ReadXml(XElement xparentSuite, Suite parentSuite)
{
foreach (XElement xSuite in xparentSuite.Elements("suite"))
{
parentSuite.type = (string)xSuite.Attribute("type");
if (parentSuite.suites == null) parentSuite.suites = new List<Suite>();
Suite newSuite = new Suite();
parentSuite.suites.Add(newSuite);
XElement properties = xSuite.Element("properties");
if (properties != null)
{
parentSuite.properties = properties.Elements("property")
.GroupBy(x => (string)x.Attribute("name"), y => (string)y)
.ToDictionary(x => x.Key, y => y.FirstOrDefault());
}
parentSuite.cases = xSuite.Elements("case").Select(x => new Case(x)).ToList();
ReadXml(xSuite, newSuite);
}
}
}
public class Case
{
public string id { get; set; }
public string name { get; set; }
public Dictionary<string, string> properties { get; set; }
public Case() { }
public Case(XElement _case)
{
id = (string)_case.Attribute("id");
name = (string)_case.Attribute("name");
properties = _case.Descendants("property")
.GroupBy(x => (string)x.Attribute("name"), y => (string)y)
.ToDictionary(x => x.Key, y => y.FirstOrDefault());
}
}
}

I am getting an empty XmlNodeList eventhough XML is wellformed

I have a well formed xml that i want to parse and retrieve the line elements.
But I keep getting an empty XmlNodeList blocks. What am I doing wrong?
Thanks!
XmlDocument doc = new XmlDocument();
doc.Load("file.xml"));
XmlNodeList blocks = doc.DocumentElement.SelectNodes("/document/page/block");
foreach (XmlNode block in blocks)
{
//keep iterating over `par` elements in `text`
}
file.xml:
<document xmlns="http://www.abbyy.com/FineReader_xml/FineReader10-schema-v1.xml" version="1.0" producer="ABBYY FineReader Engine 11" languages="" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.abbyy.com/FineReader_xml/FineReader10-schema-v1.xml http://www.abbyy.com/FineReader_xml/FineReader10-schema-v1.xml">
<page width="1043" height="653" resolution="300" originalCoords="1">
<block blockType="Text" blockName="" l="43" t="27" r="736" b="147"><region><rect l="641" t="27" r="735" b="28"/><rect l="520" t="28" r="735" b="29"/><rect l="399" t="29" r="735" b="30"/><rect l="277" t="30" r="735" b="31"/><rect l="156" t="31" r="735" b="32"/><rect l="43" t="32" r="735" b="83"/><rect l="43" t="83" r="736" b="86"/><rect l="44" t="86" r="736" b="142"/><rect l="44" t="142" r="643" b="143"/><rect l="44" t="143" r="521" b="144"/><rect l="44" t="144" r="400" b="145"/><rect l="44" t="145" r="279" b="146"/><rect l="44" t="146" r="157" b="147"/></region>
<region>
</region>
<text>
<par lineSpacing="816">
<line baseline="58" l="314" t="28" r="734" b="55">
<formatting lang="EnglishUnitedStates">Information priveid</formatting>
</line>
<line baseline="92" l="377" t="61" r="673" b="89">
<formatting lang="EnglishUnitedStates">Canyouread this</formatting>
</line>
</par>
<par>
<line baseline="146" l="45" t="110" r="679" b="146">
<formatting lang="EnglishUnitedStates"> This can not be happening?</formatting>
</line>
</par>
</text>
</block>
</page>
</document>
It's because your <document> element has a namespace.
Try this:
var nsManager = new XmlNamespaceManager(doc.NameTable);
nsManager.AddNamespace("nsp", "http://www.abbyy.com/FineReader_xml/FineReader10-schema-v1.xml");
XmlNodeList blocks = doc.SelectNodes("//nsp:page/nsp:block", nsManager);
Or, if possible, remove the namespace from your document and use your original code.
Try xml linq
Below is using anonymous types
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication16
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
XNamespace ns = ((XElement)doc.FirstNode).Name.Namespace;
var pars = doc.Descendants(ns + "par").Select(x => new {
lineSpacing = (int?)x.Attribute("lineSpacing"),
lines = x.Elements(ns + "line").Select(y => new {
baseline= (int)y.Attribute("baseline"),
l = (int)y.Attribute("l"),
t = (int)y.Attribute("t"),
r = (int)y.Attribute("r"),
b = (int)y.Attribute("b"),
formatting = (string)y.Element(ns + "formatting"),
lang = (string)y.Element(ns + "formatting").Attribute("lang")
}).ToList()
}).ToList();
}
}
}
Below is using Class structures
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication16
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
XNamespace ns = ((XElement)doc.FirstNode).Name.Namespace;
Document.documents = doc.Descendants(ns + "par").Select(x => new Document() {
lineSpacing = (int?)x.Attribute("lineSpacing"),
lines = x.Elements(ns + "line").Select(y => new Line() {
baseline = (int)y.Attribute("baseline"),
l = (int)y.Attribute("l"),
t = (int)y.Attribute("t"),
r = (int)y.Attribute("r"),
b = (int)y.Attribute("b"),
formatting = (string)y.Element(ns + "formatting"),
lang = (string)y.Element(ns + "formatting").Attribute("lang")
}).ToList()
}).ToList();
}
}
public class Document
{
public static List<Document> documents = new List<Document>();
public int? lineSpacing { get; set; }
public List<Line> lines { get; set; }
}
public class Line
{
public int baseline { get; set; }
public int l { get; set; }
public int t { get; set; }
public int r { get; set; }
public int b { get; set; }
public string formatting { get; set; }
public string lang { get; set; }
}
}

How to parse xml with LINQ to an Object with XDocument

I have an xml file as below:
<Message xsi:schemaLocation ="..">
<Header>..</Header>
<Body>
<History
xmlns="..">
<Number></Number>
<Name></Name>
<Item>
<CreateDate>..</CreateDate>
<Type>..</Type>
<Description></Description>
</Item>
<Item>
<CreateDate>..</CreateDate>
<Type>..</Type>
<Description>1..</Description>
<Description>2..</Description>
</Item>
</History>
</Body>
</Message>
I would like to create and object from this as History object.
public class History
{
public string Name { get; set; }
public string Number { get; set; }
public List<Item> Items { get; set; }
}
var xElement = XDocument.Parse(xmlString);
XElement body = (XElement)xElement.Root.LastNode;
XElement historyElement = (XElement)body.LastNode;
var history = new History
{
Name = (string)historyElement.Element("Name"),
Number = (string)historyElement.Element("Number"),
Items = (
from e in historyElement.Elements("Item")
select new Item
{
CraeteDate = DateTime.Parse(e.Element("CreateDate").Value),
Type = (string)e.Element("Type").Value,
Description = string.Join(",",
from p in e.Elements("Description") select (string)p.Element("Description"))
}).ToList()
};
Why this does not work?
The values are always null.
It seems that "historyElement.Element("Name")" is always null even there is an element and value for the element.
Any idea what am I missing?
Thanks
It's due to the namespace, try doing this:
XNamespace ns = "http://schemas.microsoft.com/search/local/ws/rest/v1";// the namespace you have in the history element
var xElement = XDocument.Parse(xmlString);
var history= xElement.Descendants(ns+"History")
.Select(historyElement=>new History{ Name = (string)historyElement.Element(ns+"Name"),
Number = (string)historyElement.Element(ns+"Number"),
Items = (from e in historyElement.Elements(ns+"Item")
select new Item
{
CraeteDate= DateTime.Parse(e.Element(ns+"CreateDate").Value),
Type = (string) e.Element(ns+"Type").Value,
Description= string.Join(",",
from p in e.Elements(ns+"Description") select (string)p)
}).ToList()
}).FirstOrDefault();
If you want to read more about this subject, take a look this link
A couple of minor things here, the xml was malformed here. So had to take a while to test and make it work.
You have an xsi in the front which I assume should be somewhere mentioned in the xsd.
Turns out you have to append the namespace if your xml node has a namespace attached to it as you are parsing the xml tree here:
My sample solution looked like this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
namespace ConsoleApplication1
{
public class History
{
public string Name { get; set; }
public string Number { get; set; }
public List<Item> Items { get; set; }
}
public class Item
{
public DateTime? CreateDate { get; set; }
public string Type { get; set; }
public string Description { get; set; }
}
class Program
{
static void Main(string[] args)
{
string xmlString =
#"<Message>
<Header>..</Header>
<Body>
<History
xmlns=""http://schemas.somewhere.com/types/history"">
<Number>12</Number>
<Name>History Name</Name>
<Item>
<CreateDate></CreateDate>
<Type>Item 1 Type</Type>
<Description>Item 1 Description</Description>
</Item>
<Item>
<CreateDate></CreateDate>
<Type>Item 2 Type</Type>
<Description>Item 2 Description 1</Description>
<Description>Item 2 Description 2</Description>
</Item>
</History>
</Body>
</Message>";
XNamespace ns = "http://schemas.somewhere.com/types/history";
var xElement = XDocument.Parse(xmlString);
var historyObject = xElement.Descendants(ns +"History")
.Select(historyElement => new History
{
Name = historyElement.Element(ns + "Name")?.Value,
Number = historyElement.Element(ns + "Number")?.Value,
Items = historyElement.Elements(ns + "Item").Select(x => new Item()
{
CreateDate = DateTime.Parse(x.Element(ns + "CreateDate")?.Value),
Type = x.Element(ns + "Type")?.Value,
Description = string.Join(",", x.Elements(ns + "Description").Select(elem=>elem.Value))
}).ToList()
}).FirstOrDefault();
}
}
}
If you dont wan't to care about finding the namespace, you might want to try the following:
var document = XDocument.Parse(xmlString);
var historyObject2 = document.Root.Descendants()
.Where(x=>x.Name.LocalName == "History")
.Select(historyElement => new History
{
Name = historyElement.Element(historyElement.Name.Namespace + "Name")?.Value,
Number = historyElement.Element(historyElement.Name.Namespace+ "Number")?.Value,
Items = historyElement.Elements(historyElement.Name.Namespace + "Item").Select(x => new Item()
{
//CreateDate = DateTime.Parse(x.Element("CreateDate")?.Value),
Type = x.Element(historyElement.Name.Namespace + "Type")?.Value,
Description = string.Join(",", x.Elements(historyElement.Name.Namespace + "Description").Select(elem => elem.Value))
}).ToList()
}).FirstOrDefault();

Get text for xml node

Sample XML:
<query yahoo:count="1" yahoo:created="2016-03-31T06:43:49Z" yahoo:lang="en-US">
<results>
<channel>
<item>
<yweather:condition code="28" date="Thu, 31 Mar 2016 08:00 AM SAST" temp="58" text="Mostly Cloudy"/>
</item>
</channel>
</results>
</query>
Code:
string weburl = "https://query.yahooapis.com/v1/public/yql?q=select%20item.condition%20from%20weather.forecast%20where%20woeid%20in%20%28select%20woeid%20from%20geo.places%281%29%20where%20text%3D%22Cape%20Town%22%29&format=xml&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys";
var xml = await new WebClient().DownloadStringTaskAsync(new Uri(weburl));
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
XmlElement root = doc.DocumentElement;
XmlNodeList nodes = root.SelectNodes("//query/results/channel/item");
foreach (XmlNode node in nodes)
{
MessageBox.Show(node.InnerXml);
}
I have been struggling to just get the temp and text outputed but I can't find way how to, this is as far as I got.
You can access XML attributes from XmlNode.Attributes property :
var condition = doc.SelectSingleNode("/query/results/channel/item/*");
MessageBox.Show(condition.Attributes["text"].Value);
MessageBox.Show(condition.Attributes["temp"].Value);
Try this....
Usings....
using System.IO;
using System.Net;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
Classes....
[XmlRoot(ElementName = "condition", Namespace = "http://xml.weather.yahoo.com/ns/rss/1.0")]
public class Condition
{
[XmlAttribute(AttributeName = "yweather", Namespace = "http://www.w3.org/2000/xmlns/")]
public string Yweather { get; set; }
[XmlAttribute(AttributeName = "code")]
public string Code { get; set; }
[XmlAttribute(AttributeName = "date")]
public string Date { get; set; }
[XmlAttribute(AttributeName = "temp")]
public string Temp { get; set; }
[XmlAttribute(AttributeName = "text")]
public string Text { get; set; }
}
[XmlRoot(ElementName = "item")]
public class Item
{
[XmlElement(ElementName = "condition", Namespace = "http://xml.weather.yahoo.com/ns/rss/1.0")]
public Condition Condition { get; set; }
}
[XmlRoot(ElementName = "channel")]
public class Channel
{
[XmlElement(ElementName = "item")]
public Item Item { get; set; }
}
[XmlRoot(ElementName = "results")]
public class Results
{
[XmlElement(ElementName = "channel")]
public Channel Channel { get; set; }
}
[XmlRoot(ElementName = "query")]
public class Query
{
[XmlElement(ElementName = "results")]
public Results Results { get; set; }
[XmlAttribute(AttributeName = "yahoo", Namespace = "http://www.w3.org/2000/xmlns/")]
public string Yahoo { get; set; }
[XmlAttribute(AttributeName = "count", Namespace = "http://www.yahooapis.com/v1/base.rng")]
public string Count { get; set; }
[XmlAttribute(AttributeName = "created", Namespace = "http://www.yahooapis.com/v1/base.rng")]
public string Created { get; set; }
[XmlAttribute(AttributeName = "lang", Namespace = "http://www.yahooapis.com/v1/base.rng")]
public string Lang { get; set; }
}
Code...
XmlDocument xmlDocument = new XmlDocument();
try
{
xmlDocument.Load("https://query.yahooapis.com/v1/public/yql?q=select%20item.condition%20from%20weather.forecast%20where%20woeid%20in%20%28select%20woeid%20from%20geo.places%281%29%20where%20text%3D%22Cape%20Town%22%29&format=xml&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys");
string XMLxmlDocument = xmlDocument.InnerXml.ToString();
byte[] BUFXML = ASCIIEncoding.UTF8.GetBytes(XMLxmlDocument);
MemoryStream ms1 = new MemoryStream(BUFXML);
XmlSerializer DeserializerPlaces = new XmlSerializer(typeof(Query));//, new XmlRootAttribute("Query"));
using (XmlReader reader = new XmlTextReader(ms1))
{
Query dezerializedXML = (Query)DeserializerPlaces.Deserialize(reader);
string temp = dezerializedXML.Results.Channel.Item.Condition.Temp;
string text = dezerializedXML.Results.Channel.Item.Condition.Text;
}// Put a break-point here, then mouse-over temp and text, you should have you values (dezerializedXML contains the entire object)
}
catch (System.Exception)
{
throw;
}
I used xml linq along with Regex. I had to fix issues with your xml. I think the main issue was the namespaces.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Text.RegularExpressions;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string xml =
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>" +
"<Root xmlns:yahoo=\"abc\" xmlns:yweather=\"def\">" +
"<query yahoo:count=\"1\" yahoo:created=\"2016-03-31T06:43:49Z\">" +
"yahoo:lang=\"en-US\"><results>" +
"<channel>" +
"<item>" +
"<yweather:condition>" +
"code=\"28\" date=\"Thu, 31 Mar 2016 08:00 AM SAST\" temp=\"58\" text=\"Mostly Cloudy\"/>" +
"</yweather:condition>" +
"</item>" +
"</channel>" +
"</results>" +
"</query>" +
"</Root>";
XDocument doc = XDocument.Parse(xml);
string innertext = doc.Descendants().Where(x => x.Name.LocalName == "condition").Select(y => y.Value).FirstOrDefault();
string pattern = "\\s?(?'name'[^=]+)=\"(?'value'[^\"]+)\"";
MatchCollection matches = Regex.Matches(innertext, pattern);
foreach (Match match in matches)
{
Console.WriteLine("Name : {0}, Value : {1}", match.Groups["name"].Value, match.Groups["value"].Value);
}
Console.ReadLine();
}
}
}

Categories

Resources