Linq to XML Question - c#

Given the following XML, what query can I use to extract the value of preapprovalKey to a string variable? Still a little new to LINQ to XML.
<?xml version="1.0" encoding="UTF-8" ?>
- <ns2:PreapprovalResponse xmlns:ns2="http://svcs.paypal.com/types/ap">
- <responseEnvelope>
<timestamp>2011-04-05T18:35:32.952-07:00</timestamp>
<ack>Success</ack>
<correlationId>7cec030fa3eb2</correlationId>
<build>1655692</build>
</responseEnvelope>
<preapprovalKey>PA-9AG427954Y7578617</preapprovalKey>
</ns2:PreapprovalResponse>

XDocument doc = XDocument.Load("test.xml");
string preapprovalKey = doc.Descendants("preapprovalKey").Single().Value;

See below my exmaple, it help you to resolve your issue and problem. :)
Consider this below XML is there as one of the SQL table's column.
<Root>
<Name>Dinesh</Name>
<Id>2</Id>
</Root>
The objective of the query is to fetch the Name from the XML. In this example we will fetch the 'Dinesh' as the value.
var Query = (from t in dbContext.Employee.AsEnumerable()
where t.active == true
select new Employee
{
Id = t.AtpEventId,
Name = XDocument.Parse(t.Content).Descendants("Root").Descendants("Name").ToList().
Select(node => node.Value.ToString()).FirstOrDefault()
});
Note the following :-
Here in above LINQ , t.active == true is just an example to make some condition if needed.
Please note, in the above LInQ query, always use the AsEnumerable(), as I did in the
first file of the Linq query.exmaple(var Query = (from t in dbContext.Employee.AsEnumerable())
Descendants("Root").Descendants("Name") , Here Root should be the Element matching with the XML, And under the Root we have Name element, thats why we wrote
Descendants("Root").Descendants("Name")
For any further clarification you can reach me via danish.eggericx#gmail.com

Related

Using LINQ to exclude a Child Node from a collection of the same name

Per this XML, please note that BBB exists on two node levels.
<?xml version="1.0" encoding="utf-8"?>
<AAA>
<BBB>
<BBB>ONE</BBB>
<CCC>1</CCC>
<DDD>2</DDD>
<EEE>3</EEE>
</BBB>
<BBB>
<BBB>TWO</BBB>
<CCC>4</CCC>
<DDD>5</DDD>
<EEE>6</EEE>
</BBB>
<BBB>
<BBB>THREE</BBB>
<CCC>7</CCC>
<DDD>8</DDD>
<EEE>9</EEE>
</BBB>
</AAA>
I want to derive a collection of top level BBB's and extract them to their own file, with a file name based on the inner BBB.
My code is this:
XDocument xdoc = XDocument.Load(sourceFile);
var lv1s = from lv1 in xdoc.Descendants("AAA") select lv1;
var lv2s = from lv2 in xdoc.Descendants("BBB") select lv2;
foreach (var lv2 in lv2s)
{
var name = lv2.Element("BBB").Value;
lv2.Save(#"c:\temp\" + name + ".xml");
}
Problem is, LVL2 is picking up both the parent and descendants BBB.
Can't seem to find a method that effectively filters out descendants.
For example I thought this was the key, but it yielded no results:
var lv2s = from lv2 in xdoc.Elements("BBB") select lv2;
Hoping you can provide me a ways to deal with the problem.
-------------------- EDIT --------------------
Okay I see what I did wrong. A typo.
LVL2 should have leveraged LVL1, like this:
var lv2s = from lv2 in lv1s.Elements("BBB") select lv2;
That said, octavioccl's approach was much better than the bloated solution I came up with:
var parentBbbs =xdoc.Element("AAA").Elements("BBB");
You need to start getting the root element and then select the parent BBBs using Elements method:
var parentBbbs =xdoc.Element("AAA").Elements("BBB");
Just document.Root.Elements() should work.
Basically Descendants() recurses, whereas Elements() only gets direct children.

LINQ TO XML retrieving Child Element Value

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");

Cannot query XML document using XDocument and get desired results

I'm trying to use the Bing maps API, which returns an XML document. The document (simplified but keeping structure) is
<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">
<StatusCode>
200
</StatusCode>
<ResourceSets>
<ResourceSet>
<Resources>
<TrafficIncident>
<Severity>
Minor
</Severity>
<RoadClosed>
false
</RoadClosed>
</TrafficIncident>
</Resources>
</ResourceSet>
</ResourceSets>
</Response>
In this case, there is only 1 traffic issue but there could be many.
I'm trying to extract if the road is closed and the severity
The XML is stored in a xd object (of type XDocuement)
The following works fine (no error but returns all the elements)
var allNodes = (from x in xd.Descendants()
select x).ToList();
but if I add an element name then it returns a list with 0 items
var allNodes = (from x in xd.Descendants("Resources")
select x).ToList();
I thought the above code is saying:
from xd, grab all of the descendants of the "Resources" element
If my understanding is correct, why does it return 0 results
You must include your (default) XML namespace like so:
var name = XName.Get("Resources", "http://schemas.microsoft.com/search/local/ws/rest/v1");
var allNodes = (from x in xd.Descendants(name)
select x).ToList();
You must not forget the XML Namespace.
XNamespace search = "http://schemas.microsoft.com/search/local/ws/rest/v1";
var allNodes = (from x in xd.Descendants(search + "Resources")
select x).ToList();

XDocument LINQ search based on attribute

I have an XML document which I load from the disk
XDocument events = XDocument.Load("Content/GameData/events.xml");
The contents of this xml are the following:
<?xml version='1.0' encoding='UTF-8'?>
<Events>
<level1>
<NarrationEvent code="lvl1_fridge">
I can't even remember when I last ate.
I am not hungry though.
</NarrationEvent>
<NarrationEvent code="lvl1_tv">
Why do I even have a TV?
Oh right, I use it as a screen for my laptop.
</NarrationEvent>
<NarrationEvent code="lvl1_bed">
Oh man, I am beat.
</NarrationEvent>
<NarrationEvent code="lvl1_computer">
Oh, look at that. The project has been compiled.
</NarrationEvent>
</level1>
<level2>
</level2>
<level3>
</level3>
<level4>
</level4>
<cave>
</cave>
</Events>
I use this code here supposedly select the appropriate NarrationEvent element, based on its attribute "code"
IEnumerable<XElement> v =
(from narrationEvent in events.Elements("NarrationEvent")
where (string)narrationEvent.Attribute("code") == code
select narrationEvent);
foreach (XElement page in v)
{
//Console.WriteLine("ff");
narration.Add(page.Value);
}
This returns nothing, my XElement Ienumerable is empty. I used breakpoints and the code value is passed to this method just fine. e.g. "lvl1_bed"
What is wrong with this code?
You can use the Descendants-Method to get your NarrationEvent-Element. I have updated your code accordingly.
IEnumerable<XElement> v = from narrationEvent in events.Descendants("NarrationEvent")
where narrationEvent.Attribute("code").Value == code
select narrationEvent;

Error on converting XML to object using LINQ

I have this xml:
<?xml version="1.0" encoding="utf-8"?>
<Packet>
<Header>
<Id>1234-1234-1234</Id>
</Header>
<Customers>
<Customer>
<Name>Try</Name>
<Age>20</Age>
</Customer>
</Customers>
</Packet>
And this is how I convert it to object:
XDocument xdoc = XDocument.Load(xml);
List<Customer> customers = (from customer in xdoc.Element("Customers").Element("Customer")
select new Customer
{
Name = customer.Element("Name").Value,
Age = customer.Element("Age").Value
}).ToList();
My problem is when I tried to run this code, I got an exception error saying that object reference not set to an instance.
But when i changed my xml to this:
<?xml version="1.0" encoding="utf-8"?>
<Customers>
<Customer>
<Name>Try</Name>
<Age>20</Age>
</Customer>
</Customers>
It started working and I am getting the name and age. However, the packet and header is one of the requirements on my xml files. How am I gonna do that?
EDIT:
Thanks for all the solutions! They are all working, but may I know what is the best to use (best practices, etc) Thanks!
You can use Descendants() method to find elements in xml tree.
List<Customer> customers = (from customer in xdoc.Descendants("Customer")
select new Customer
{
Name = customer.Element("Name").Value,
Age = customer.Element("Age").Value
}).ToList();
Change your query source to:
xdoc.Root.Element("Customers").Elements("Customer")
Element method looks for the element on current level, which is the root for XDocument. That's why the query didn't work.
Try changing your LINQ query to:
XDocument xdoc = XDocument.Load(xml);
List<Customer> customers = (from customer in xdoc.Element("Packet").Element("Customers").Element("Customer")
select new Customer
{
Name = customer.Element("Name").Value,
Age = customer.Element("Age").Value
}).ToList();
Because your Customers element is located inside your Packet element.

Categories

Resources