Attempting to get single value from XDocument, nothing appears to work - c#

I am just trying to get the value from MessageInfo.. Sender here is an excerpt of the xml. I just want the "Senders" value. I have tried many different things with XDocument, and wanted to use a Linq Query
I have tried,
var query1 = doc.Descendants("MessageInfo").Select(s => new MessageInfo
{
SYSGENID = s.Element("SysGenID").Value,
TIME_STAMP = s.Element("TimeStamp").Value,
SENDER = s.Element("Sender").Value,
RECEIVER = s.Element("Receiver").Value,
ENTITY_CODE = s.Element("EntityCode").Value
}).FirstOrDefault();
the query1 returns null. Following is example of xml
I also have tried
XDocument doc = XDocument.Load(filePath);
var messageInfo = doc.Root.Elements("MessageInfo");
var res = from m in messageInfo
select new
{
msgInfo = m.Element("MessageInfo").Value
};
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<PutSchedule xmlns="http://www.nwpp.org/eide">
<MessageInfo>
<SysGenID>4431</SysGenID>
<TimeStamp>2014-08-12T10:34:28.068000</TimeStamp>
<Sender>611</Sender>
<Receiver>WECC</Receiver>
<EntityCode>611</EntityCode>
</MessageInfo>
<Schedules>
<Schedule>
<ScheduleDescription>
<StartTime>2014-08-12T00:00:00</StartTime>
<EndTime>2014-08-15T00:00:00</EndTime>
<AccountCode>259S.NRGREEN_G1.BaseMW</AccountCode>
</ScheduleDescription>
<Quantities>

You have a namespace that you have to use.
XNamespace ns = "http://www.nwpp.org/eide";
var query1 = doc.Descendants(ns +"MessageInfo").Select(s => new MessageInfo
{
SYSGENID = s.Element(ns +"SysGenID").Value,
TIME_STAMP = s.Element(ns +"TimeStamp").Value,
SENDER = s.Element(ns +"Sender").Value,
RECEIVER = s.Element(ns +"Receiver").Value,
ENTITY_CODE = s.Element(ns +"EntityCode").Value
}).FirstOrDefault();

Related

XDocument just reads the first title?

I need to parse xml but my code just parses one title not all.
How can I parse part ?
This is my code:
CustomResponse itemCustom = new CustomResponse ();
XDocument response = XDocument.Parse(responseXml);
XElement rootElement = response.Root;
foreach (XElement sellResponse in rootElement.Elements())
{
itemCustom .ErrorCode = sellResponse.Element("ErrorCode").Value;
itemCustom .ErrorMessage = sellResponse.Element("ErrorMessage").Value;
itemCustom .CustomerID= sellResponse.Element("CustomerID").Value;
itemCustom .CustomerType= sellResponse.Element("CustomerType").Value;
}
This is my xml:
<?xml version="1.0" encoding="utf-8"?>
<TINS_XML_DATA>
<Header>
<ErrorCode>WAATS</ErrorCode>
<ErrorMessage>UTL</ErrorMessage>
</Header>
<Customer>
<CustomerID>UTL11111111111111111111</CustomerID>
<CustomerType>NSell</CustomerType>
</Customer>
</TINS_XML_DATA>
Try something like this:
foreach (XElement sellResponse in rootElement.Elements())
{
if (sellResponse.Name == "Header")
{
itemCustom.ErrorCode = sellResponse.Element("ErrorCode").Value;
itemCustom.ErrorMessage = sellResponse.Element("ErrorMessage").Value;
}
else if (sellResponse.Name == "Customer")
{
itemCustom.CustomerID = sellResponse.Element("CustomerID").Value;
itemCustom.CustomerType = sellResponse.Element("CustomerType").Value;
}
}
Update: You could also use XPath to find required elements as like below:
var xDoc = new XmlDocument();
xDoc.LoadXml(xml);
var errorMessage = xDoc.SelectNodes("//ErrorMessage")[0].InnerText;
This is my solved:
var xDoc = new XmlDocument();
xDoc.LoadXml(responseXml);
itemSell.ErrorCode = xDoc.SelectNodes("//ErrorCode")[0].InnerText;
itemSell.ErrorMessage = xDoc.SelectNodes("//ErrorMessage")[0].InnerText;
itemSell.CustomerID= xDoc.SelectNodes("//CustomerID")[0].InnerText;

How to get separate values from Xlement

This is a portion of XML I'm trying to parse
<BRTHDATES>
<BRTHDATE value="5/1/1963" code="B"/>
</BRTHDATES>
var birthdates = xmlDoc.XPathSelectElements("/INDV/PERSON/BRTHDATES").Elements().Where(e => e.Name == "BRTHDATE");
xe = birthdates.Elements().Where(e => e.Name == "BRTHDATE");
bbs = from b in birthdates
select new
{
Birthdays = b.FirstAttribute.Value,
Code = b?.Value
};
var status = birthdates.Elements().Where(e => e.Name.LocalName == "BRTHDATE").Single().Value;
When I try to get "Value" from the Element I get an empty string. I can't get anything for the "code" attribute.
It sure seems like this should be a lot easier...
You can try below code. I've already tested through a test project and got the require value.
string personBirthday = string.Empty;
string soapResult = #"<?xml version=""1.0"" encoding=""utf - 8"" ?><INDV> <PERSON> <BRTHDATES><BRTHDATE value = ""5/1/1963"" code = ""B"" /> </BRTHDATES></PERSON></INDV> ";
XmlDocument doc = new XmlDocument();
doc.Load(new StringReader(soapResult));
XmlNodeList person = doc.GetElementsByTagName("BRTHDATES");
if (person[0].ChildNodes.Count > 0)
{
foreach (XmlNode item in person[0].ChildNodes)
{
if (item.Name.Trim().Equals("BRTHDATE"))
{
personBirthday = !string.IsNullOrEmpty(item.Attributes[0].Value) ? item.Attributes[0].Value.Trim() : string.Empty;
}
}
}
Here is the solution
You can select specific Element from a Xml. Just try below sample code
XmlNodeList generalTabNodeList = xmlDocument.SelectNodes("/INDV/PERSON/BRTHDATES");
foreach (XmlNode node in generalTabNodeList)
{
if (node.ChildNodes.Count > 0)
{
string birthdate = !string.IsNullOrEmpty(node.ChildNodes[0].ToString()) ? node.ChildNodes[2].InnerText.ToString() : string.Empty;
}
}
I can't quite follow what you are trying to do, but, this should get you going:
For an XML file that looks like this:
<?xml version="1.0" encoding="utf-8" ?>
<INDV>
<PERSON>
<BRTHDATES>
<BRTHDATE value="5/1/1963" code="B"/>
</BRTHDATES>
</PERSON>
</INDV>
(Note, this is an entire XML document - one that matches your code, not just the snippet you provided (that doesn't match your code))
This code will pick out the value and code attributes:
using (var xmlStream = new FileStream("Test.xml", FileMode.Open))
{
XDocument xmlDocument = XDocument.Load(xmlStream);
var birthDateElements = xmlDocument.XPathSelectElements("/INDV/PERSON/BRTHDATES/BRTHDATE");
var birthDateElement = birthDateElements.FirstOrDefault();
if (birthDateElement != null)
{
var attributes = birthDateElement.Attributes();
var valueAttribute = attributes.Where(a => a.Name == "value");
var codeAttribute = attributes.Where(a => a.Name == "code");
}
}
You can play around with this code to figure out what you want to do. Whatever you do, don't pick out attributes by position, pick them out by name.

Using Linq to get XML data from database

I'm struggling to get the values of a single xml node using Linq.
Here is my XML.
<?xml version="1.0" encoding="utf-8"?>
<record>
<AddressLine1>abcd street</AddressLine1>
<AddressLine2>xyz AVE</AddressLine2>
<AddressCity>Illinois</AddressCity>
<AddressState>Chicago</AddressState>
<AddressZip>23434</AddressZip>
</record>
And here is my c# code
XElement xmlDoc = XElement.Parse(varQ.Content);
//When I debug I find that xmlDoc contains the XML. So that is alright.
var q = (from lpi in xmlDoc.Descendants("record")
select new { AddressLine1 = lpi.Element("AddressLine1").Value,
AddressLine2 = lpi.Element("AddressLine2").Value,
AddressCity = lpi.Element("AddressCity").Value,
AddressCountry = lpi.Element("AddressCountry").Value,
AddressState = lpi.Element("AddressState").Value,
AddressZip = lpi.Element("AddressZip").Value,
}).FirstOrDefault();
var q shows null. Can u please help me find out what is wrong here?
Replace Descendants on DescendantsAndSelf:
string xml = #"<?xml version=""1.0"" encoding=""utf-8""?>
<record>
<AddressLine1>abcd street</AddressLine1>
<AddressLine2>xyz AVE</AddressLine2>
<AddressCity>Illinois</AddressCity>
<AddressState>Chicago</AddressState>
<AddressZip>23434</AddressZip>
</record>";
XElement xmlDoc = XElement.Parse(xml);
var q = (from lpi in xmlDoc.DescendantsAndSelf("record")
select new
{
AddressLine1 = (string)lpi.Element("AddressLine1"),
AddressLine2 = (string)lpi.Element("AddressLine2"),
AddressCity = (string)lpi.Element("AddressCity"),
AddressCountry = (string)lpi.Element("AddressCountry"),
AddressState = (string)lpi.Element("AddressState"),
AddressZip = (string)lpi.Element("AddressZip"),
}).FirstOrDefault();
Console.WriteLine(q);
Print:
{ AddressLine1 = abcd street, AddressLine2 = xyz AVE, AddressCity = Illinois, AddressCountry = , AddressState = Chicago, AddressZip = 23434 }
Link: https://dotnetfiddle.net/fXQivX

XML parsing with LINQ, has 2 tags with the same name but different level and not always has a value

I have the following XML:
<request>
<book>
<id>1833801</id>
<title>The Yiddish Policemen's Union </title>
<work>
<id>1234</id>
<name/>
</work>
<similar_books>
<book><id>243859</id><title>Stations of Tide</title> <isbn>0380817616</isbn>
<authors><author><id>14454</id><name>Michael Swanwick</name></author> </authors>
</book>
</similar_books>
<authors>
<author>
<id>2715</id><name>Michael Chabon</name>
<ratings_count>215884</ratings_count></author>
</authors>
<popular_shelves>
<shelf name="jewish" count="104"/><shelf name="sci-fi" count="100"/>
</popular_shelves>
</book>
</request>
I want to have all tags with their respective values, and I am using following code:
HttpWebRequest oReq = (HttpWebRequest)WebRequest.Create(uriRoot);
HttpWebResponse resp = (HttpWebResponse)oReq.GetResponse();
log.Info(" (ISBN= " + isbn10 + ") Http request has response.");
if (resp.ContentType.StartsWith("application/xml", StringComparison.InvariantCultureIgnoreCase))
{
Stream resultStreamISBN = resp.GetResponseStream();
Encoding encode = System.Text.Encoding.GetEncoding("utf-8"); //encoding for non-latin chars
StreamReader responseReader = new StreamReader(resultStreamISBN, encode);
XDocument xdoc = XDocument.Parse(responseReader.ReadToEnd());
var books = (from u in xdoc.Descendants().Elements("book")
select new
{
id = (string)u.Element("title"),
title = (string)u.Element("title"),
works = (from i in u.Elements("work")
select new
{
work_best_book_id = (int)i.Element("id"),
work_name = (string)i.Element("name"),
}).ToList(),
authors = (from i in u.Elements("authors").Elements("author")
select new
{
id = (int)i.Element("id"),
name = (string)i.Element("name"),
rating = (int)i.Element("rating_count")
}).ToList(),
popular_shelves = (from i in u.Elements("popular_shelves").Elements("shelf")
select new
{
name = (string)i.Attribute("name"),
count = (int)i.Attribute("count")
}).ToList(),
}).ToList();
The code returns null values and is not working properly. I also should note that different xml files may not have values for all the tags.
Any suggestions on how I can improve my code?
Check for missing elements like such:
name = i.Element("name") == null ? null : i.Element("name")
For value types, you make have to change them to nullable types for this to work correctly.
You can transform
id = (int)i.Element("id"),
to
id = (int?)i.Element("id"),
Whole modified code
// I am inserting the following line to demonstrate how I load the XML in test code
// Basically, I copied & pasted xml in a file OP gave named request.xml
//XDocument xdoc = XDocument.Load( #"d:\Data\request.xml");
EDIT
XDocument xdoc = XDocument.Load("http://www.goodreads.com/book/isbn?isbn=0007295685&key=lbScLXWyNGQ1q0BDoFFSg");
var books = (from u in xdoc.Descendants().Elements("book")
select new
{
id = (string)u.Element("title"),
title = (string)u.Element("title"),
works = (from i in u.Elements("work")
select new
{
work_best_book_id = (int?)i.Element("id"),
work_name = (string)i.Element("name"),
}).ToList(),
authors = (from i in u.Elements("authors").Elements("author")
select new
{
id = (int?)i.Element("id"),
name = (string)i.Element("name"),
rating = (int?)i.Element("rating_count")
}).ToList(),
popular_shelves = (from i in u.Elements("popular_shelves").Elements("shelf")
select new
{
name = (string)i.Attribute("name"),
count = (int?)i.Attribute("count")
}).ToList(),
}).ToList();

read xml with same elements name

I have xml in format below:
<?xml version="1.0" encoding="UTF-8" standalone="true"?>
-<draw><drawNo>381555</drawNo>
<drawTime>2013-04-29T19:55:00+03:00</drawTime>
<result>8</result>
<result>10</result>
<result>13</result>
<result>15</result>
<result>20</result>
<result>21</result>
<result>22</result>
<result>25</result>
<result>28</result>
<result>29</result>
<result>34</result>
<result>36</result>
<result>44</result>
<result>46</result>
<result>52</result>
<result>62</result>
<result>63</result>
<result>72</result>
<result>73</result>
<result>75</result>
</draw>
I need to split the data...
I've tried the code below:
XDocument loadeddata = XDocument.Parse(e.Result);
var data = from query in loadeddata.Descendants("draw")
select new KinnoResults()
{
DrawNo = (String) query.Element("drawNo").Value,
DrawTime = (String) query.Element("drawTime").Value,
result1 = (String)query.Element("result").Value,
result2 = (String)query.Element("result").Value
};
List<KinnoResults> list = data.ToList();
But result1 and result2 hava the same value 8.
Any idea please?
var drawNo = loadeddata.Root.Element("drawNo").Value;
var drawTime = loadeddata.Root.Element("drawTime").Value;
var results = loadeddata.Descendants("result").Select(d => d.Value).ToList();
use Elements, it gets you a collection
select new KinnoResults()
{
DrawNo = (String)query.Elements("drawNo").Value,
DrawTime = (String)query.Element("drawTime").Value,
result1 = (String)query.Elements("result").ToList()[0].Value,
result2 = (String)query.Elements("result").ToList()[1].Value
};

Categories

Resources