I want to read below XMLfile with C# LINQ.
I have tried this code in C#. But not able to get address element data.
CODE:
XNamespace ns = "http://www.w3.org/2001/XMLSchema";
XNamespace nsa = "http://www.w3.org/2001/XMLSchema-instance";
var Address = from r in XDocumentdata.Descendants(ns + "Address")
select new
{
Locality = r.Element(nsa + "Locality").Value,
CountryRegion = r.Element(nsa + "CountryRegion").Value
};
foreach (var r in Address)
{
string CountryRegion = r.CountryRegion;
string Locality = r.Locality;
}
XML:
<Response xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/search/local/ws/rest/v1">
<Copyright>Copyright © 2015 Microsoft and its suppliers. All rights reserved. This API cannot be accessed and the content and any results may not be used, reproduced or transmitted in any manner without express written permission from Microsoft Corporation.</Copyright>
<BrandLogoUri>http://dev.virtualearth.net/Branding/logo_powered_by.png</BrandLogoUri>
<StatusCode>200</StatusCode>
<StatusDescription>OK</StatusDescription>
<AuthenticationResultCode>ValidCredentials</AuthenticationResultCode>
<TraceId>1cf1896a29234bc583b75487b57e343f|HK20271655|02.00.163.1200|HK2SCH010280821, i-d219511f.ap-southeast-1b</TraceId>
<ResourceSets>
<ResourceSet>
<EstimatedTotal>5</EstimatedTotal>
<Resources>
<Location>
<Name>Panjagutta, Hyderabad 500082, India</Name>
<Point>
<Latitude>17.4176132</Latitude>
<Longitude>78.449595</Longitude>
</Point>
<BoundingBox>
<SouthLatitude>17.41759</SouthLatitude>
<WestLongitude>78.44907</WestLongitude>
<NorthLatitude>17.41764</NorthLatitude>
<EastLongitude>78.4502</EastLongitude>
</BoundingBox>
<EntityType>Address</EntityType>
<Address>
<AddressLine>Panjagutta</AddressLine>
<AdminDistrict>TS</AdminDistrict>
<AdminDistrict2>Hyderabad</AdminDistrict2>
<CountryRegion>India</CountryRegion>
<FormattedAddress>Panjagutta, Hyderabad 500082, India</FormattedAddress>
<Locality>Hyderabad</Locality>
<PostalCode>500082</PostalCode>
</Address>
<Confidence>Medium</Confidence>
<MatchCode>Good</MatchCode>
<GeocodePoint>
<Latitude>17.4176132</Latitude>
<Longitude>78.449595</Longitude>
<CalculationMethod>Interpolation</CalculationMethod>
<UsageType>Display</UsageType>
<UsageType>Route</UsageType>
</GeocodePoint>
</Location>
</Resources>
</ResourceSet>
</ResourceSets>
</Response>
You are using the wrong namespace. The root namespace for the document, denoted by an unaliased xmlns attribute for the XML document is http://schemas.microsoft.com/search/local/ws/rest/v1.
Use that rather than the current value of nsa.
Create a class / model that matches the structure of XML and
deserializes XML into an object or collection.
Use Linq to work with collection if you need.
And look at https://msdn.microsoft.com/en-us/library/tz8csy73(v=vs.110).aspx
Can you give this a try:
var xmlDoc = new XmlDocument();
xmlDoc.Load("your xml path");
var address = xmlDoc.GetElementsByTagName("Address");
I can access the elements inside the Address element Now.
Related
I read multiple feed from many sources with C# Console, and i have this code where i load XML From sources:
XmlDocument doc = new XmlDocument();
doc.Load(sourceURLX);
XElement xdoc = XElement.Load(sourceURLX);
How to get enclosure url and show as variable?
If I understand your question correctly (I'm making a big assumption here) - you want to select an attribute from the root (or 'enclosing') tag, named 'url'?
You can make use of XPath queries here. Consider the following XML:
<?xml version="1.0" encoding="utf-8"?>
<root url='google.com'>
<inner />
</root>
You could use the following code to retrieve 'google.com':
String query = "/root[1]/#url";
XmlDocument doc = new XmlDocument();
doc.Load(sourceURLX);
String value = doc.SelectSingleNode(query).InnerText;
Further information about XPath syntax can be found here.
Edit: As you stated in your comment, you are working with the following XML:
<item>
<description>
</description>
<enclosure url="blablabla.com/img.jpg" />
</item>
Therefore, you can retrieve the url using the following XPath query:
/item[1]/enclosure[1]/#url
With xml like below
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
<channel>
<title>title</title>
<link>https://www.link.com</link>
<description>description</description>
<item>
<title>RSS</title>
<link>https://www.link.com/xml/xml_rss.asp</link>
<description>description</description>
<enclosure url="https://www.link.com/media/test.wmv"
length="10000"
type="video/wmv"/>
</item>
</channel>
</rss>
You will get url by reading attribute
var document = XDocument.Load(sourceURLX);
var url = document.Root
.Element("channel")
.Element("item")
.Element("enclosure")
.Attribute("url")
.Value;
To get multiple urls
var urls = document.Descendants("item")
.Select(item => item.Element("enclosure").Attribute("url").Value)
.ToList();
Using foreach loop
foreach (var item in document.Descendants("item"))
{
var title = item.Element("title").Value;
var link = item.Element("link").Value;
var description = item.Element("description").Value;
var url = item.Element("enclosure").Attribute("url").Value;
// save values to database
}
I have the following XML
<ABC xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://ns.hr-xml.org/2007-04-15">
<ReceiptId>
<IdValue>123</IdValue>
</ReceiptId>
<ClientOrderId>
<IdValue>345</IdValue>
</ClientOrderId>
<AccessPoint>
<Description>My Description</Description>
</AccessPoint>
<ABCStatus>
<Status>Error</Status>
<Details>ERRORS:
Talent is already in an active process for this opening.
</Details>
<StatusDate>2015-08-05</StatusDate>
</ABCStatus>
</ABC>
I am trying to retrieve the element value 345 nested in IdValue and ClientOrderId
I have used the Linq to xml code in C# to retrieve the value with no luck
XDocument XMLResults = XDocument.Parse(sResult);
var sClientOrderID =
from nodeAElem in XMLResults.Root.Elements("ABC")
from nodeA1Elem in nodeAElem.Elements("ClientOrderId")
from nodeA11Elem in nodeA1Elem.Elements("IdValue")
select nodeA11Elem.Value;
also need to retrieve the Status Elements value which is Error for the above xml.
Any help is greatly appreciated
Your XML document is using a namespace, you have to use it in your query to make it work.
Root already brings you to ABC element, so you don't have to call Elements("ABC")
You're looking for single value, so you probably want to use Element instead of Elements.
var ns = (XNamespace)"http://ns.hr-xml.org/2007-04-15";
var sClientOrderID = (int)XMLResults.Root
.Element(ns + "ClientOrderId")
.Element(ns + "IdValue");
I have an xml file whose structure goes as under(partial)
<?xml version="1.0" encoding="UTF-8"?>
<TestRun id="ee3838c9-a7e2-4ddf-acb1-58589e39422d" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
<TestSettings name="LocalSettings" id="e445106a-c672-4959-94d3-ec8cef9ac7e4">
<Results>
<UnitTestResult executionId="0e790a10-105f-44b1-a8f7-f72709651c17" testId="ae349466-4276-cfa9-908c-026a8589473b" testName="ValidateEmailAddressAndCompanyCode7" computerName="ACCUREVDEV" duration="00:00:41.4297842" startTime="2013-02-27T23:18:52.0238567-08:00" endTime="2013-02-27T23:19:34.0057439-08:00" testType="13cdc9d9-ddb5-4fa4-a97d-d965ccfc6d4b" outcome="Passed" testListId="8c84fa94-04c1-424b-9868-57a2d4851a1d" relativeResultsDirectory="0e790a10-105f-44b1-a8f7-f72709651c17">
</UnitTestResult>
<UnitTestResult executionId="e9e7679d-fc39-43b7-a096-819f054a3795" testId="1a808be5-21a5-37c4-5892-2969707ae42f" testName="AccountExtensionSubscriptionWithOneMachineAndThreeSubscriptionsTest_withExpiredMachines" computerName="ACCUREVDEV" duration="00:00:56.1243356" startTime="2013-02-27T23:19:34.0174655-08:00" endTime="2013-02-27T23:20:30.8418287-08:00" testType="13cdc9d9-ddb5-4fa4-a97d-d965ccfc6d4b" outcome="Passed" testListId="8c84fa94-04c1-424b-9868-57a2d4851a1d" relativeResultsDirectory="e9e7679d-fc39-43b7-a096-819f054a3795">
</UnitTestResult> .............................
...............................
As can be make out that, there is a namespace involved
xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010"
Now if I do
string source = #"D:\23_18_43.trx";
XDocument xDoc = XDocument.Load(source);
var xxxx = (from data in xDoc.Descendants("Results")
select data).Descendants("UnitTestResult").ToList();
There is no value coming.
Whereas , if I omit the namespace and do my processing, it works.
How can I proceed without removing the namespace explicitly from the source file? Can it be done programatically?
Thanks
To find a node in XML with a default namespace, you need to still search for that node using the namespace.
Eg.
XNamespace defaultNs = "http://microsoft.com/schemas/VisualStudio/TeamTest/2010";
and then in your "query";
var xxxx = (from data in xDoc.Descendants(defaultNs + "Results")
select data).Descendants(defaultNs +"UnitTestResult").ToList();
I am coding for WP7. I am expecting this code below to read the XML below:
_xml = XElement.Parse(e.Result);
results.Items.Clear();
foreach (XElement value in _xml
.Descendants("ResourceSets").Descendants("ResourceSet")
.Descendants("Resources").Descendants("Location"))
{
Results _item = new Results();
_item.Place = value.Element("Name").Value;
_item.Lat = value.Element("Point").Element("Latitude").Value;
_item.Long = value.Element("Point").Element("Longitude").Value;
results.Items.Add(_item);
}
But the foreach loop wont read it and place it in the _items.
<?xml version="1.0" encoding="utf-8" ?>
<Response xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.microsoft.com/search/local/ws/rest/v1">
<Copyright>Copyright © 2011 Microsoft and its suppliers. All rights reserved. This API cannot be accessed and the content and any results may not be used, reproduced or transmitted in any manner without express written permission from Microsoft Corporation.</Copyright>
<BrandLogoUri>http://dev.virtualearth.net/Branding/logo_powered_by.png</BrandLogoUri>
<StatusCode>200</StatusCode>
<StatusDescription>OK</StatusDescription>
<AuthenticationResultCode>ValidCredentials</AuthenticationResultCode>
<TraceId>703e7f1427dd425185ded546ba8a0d2c|LTSM001154|02.00.126.3000|LTSMSNVM002008, LTSMSNVM001854, LTSMSNVM001853</TraceId>
<ResourceSets>
<ResourceSet>
<EstimatedTotal>4</EstimatedTotal>
<Resources>
<Location>
<Name>Ashford, Kent, United Kingdom</Name>
<Point>
<Latitude>51.146636679768562</Latitude>
<Longitude>0.87603025138378143</Longitude>
</Point>
<BoundingBox>
<SouthLatitude>51.076602190732956</SouthLatitude>
<WestLongitude>0.72853825986385345</WestLongitude>
<NorthLatitude>51.21656522154808</NorthLatitude>
<EastLongitude>1.0235222429037094</EastLongitude>
</BoundingBox>
<EntityType>PopulatedPlace</EntityType>
<Address>
<AdminDistrict>England</AdminDistrict>
<AdminDistrict2>Kent</AdminDistrict2>
<CountryRegion>United Kingdom</CountryRegion>
<FormattedAddress>Ashford, Kent, United Kingdom</FormattedAddress>
<Locality>Ashford</Locality>
</Address>
<Confidence>High</Confidence>
</Location>
</Resources>
</ResourceSet>
</ResourceSets>
</Response>
It looks like you're missing the namespace on each of your element names. Try this:
XNamespace xns = "http://schemas.microsoft.com/search/local/ws/rest/v1";
_xml = XElement.Parse(e.Result);
results.Items.Clear();
foreach (XElement value in _xml
.Descendants(xns + "ResourceSets").Descendants(xns + "ResourceSet")
.Descendants(xns + "Resources").Descendants(xns + "Location"))
{
Results _item = new Results();
_item.Place = value.Element(xns + "Name").Value;
_item.Lat = value.Element(xns + "Point").Element(xns + "Latitude").Value;
_item.Long = value.Element(xns + "Point").Element(xns + "Longitude").Value;
results.Items.Add(_item);
}
Is there a particular reason why you're using Descendants?
You could just do:
XmlDocument doc = new XmlDocument();
doc.Load(YourXMLPath);
XmlNode locationNode = doc["ResourceSets"]["ResourceSet"]["Resources"]["Location"];
foreach(XmlElement value in locationNode.Children)
{
Results _item = new Results();
_item.Place = value.Element("Name").Value;
_item.Lat = value.Element("Point").Element("Latitude").Value;
_item.Long = value.Element("Point").Element("Longitude").Value;
results.Items.Add(_item);
}
I don't have VS right now, but that should be close to it.
Of course a good behavior would be to check if nodes are null before getting the next one.
public ObservableCollection<Results> result = new ObservableCollection<Results>();
XDocument xmldoc = XDocument.Parse(e.Result.ToString());
var data = from c in xmldoc.Descendants("ResourceSets").Descendants("ResourceSet").Descendants("Resources").Descendants("Location")
select new Results{
Place = c.Element("Name").Value;
Lat = c.Element("Point").Element("Latitude").Value;
Long = c.Element("Point").Element("Longitude").Value;
};
foreach (Results obj in data)
{
result.Add(obj);
}
Have not tried, but this is how I do it.
Newbie with XDocuments and Linq, please suggest a solution to retrieve the data from a particular tag in the xml string:
If I have a XML string from webservice response (I formatted xml for ease):
<?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>
<GetCashFlowReportResponse xmlns="http://tempuri.org/">
<GetCashFlowReportPdf>Hello!</GetCashFlowReportPdf>
</GetCashFlowReportResponse>
</soap:Body>
</soap:Envelope>
Using the following code, I can get the value only if GetCashFlowReportResponse tag doesn't have "xmlns" attribute. Not sure why? Otherwise, it always return null.
string inputString = "<?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><GetCashFlowReportResponse xmlns=\"http://tempuri.org/\"><GetCashFlowReportPdf>Hello!</GetCashFlowReportPdf></GetCashFlowReportResponse></soap:Body></soap:Envelope>"
XDocument xDoc = XDocument.Parse(inputString);
//XNamespace ns = "http://tempuri.org/";
XNamespace ns = XNamespace.Get("http://tempuri.org/");
var data = from c in xDoc.Descendants(ns + "GetCashFlowReportResponse")
select (string)c.Element("GetCashFlowReportPdf");
foreach (string val in data)
{
Console.WriteLine(val);
}
I can't change the web service to remove that attribute. IS there a better way to read the response and get the actual data back to the user (in more readable form)?
Edited:
SOLUTION:
XDocument xDoc = XDocument.Parse(inputString);
XNamespace ns = "http://tempuri.org/";
var data = from c in xDoc.Descendants(ns + "GetCashFlowReportResponse")
select (string)c.Element(ns + "GetCashFlowReportPdf");
foreach (string val in data)
{
Console.WriteLine(val);
}
Note: Even if all the child elements doesn't have the namespace attribute, the code will work if you add the "ns" to the element as I guess childs inherit the namespace from parent (see response from SLaks).
You need to include the namespace:
XNamespace ns = "http://tempuri.org/";
xDoc.Descendants(ns + "GetCashFlowReportResponse")
XName qualifiedName = XName.Get("GetCashFlowReportResponse",
"http://tempuri.org/");
var data = from d in xDoc.Descendants(qualifiedName)
Just ask for the elements using the qualified names:
// create a XML namespace object
XNamespace ns = XNamespace.Get("http://tempuri.org/");
var data = from c in xDoc.Descendants(ns + "GetCashFlowReportResponse")
select (string)c.Element(ns + "GetCashFlowReportPdf");
Note the use of the overloaded + operator that creates a QName with a XML namespace and a local name string.