Reputation: 825
I have a xml given below
<session xmlns="http://test.net/schema/session/1.0" name="test" start="2015-07-01T07:20:31.425Z">
<download>
<filename value="/UAT/Incoming/ Status/Archive/8-22-2011 3-20-14 PM306.xml" />
<result success="false">
<message>Timeout waiting .</message>
</result>
</download>
</session>
I want to select the message
node value only if Result
node value is false.
I donot want to check on hard coded parent node like node download because it may change
Can anyone help me please..
Upvotes: 2
Views: 1755
Reputation: 117009
This worked for me:
XNamespace ns = XNamespace.Get("http://test.net/schema/session/1.0");
IEnumerable<XElement> failures =
doc
.Descendants(ns + "download")
.Concat(doc.Descendants(ns + "upload"))
.Elements(ns + "result")
.Elements(ns + "message")
.Where(e => e.Parent.Attributes("success").Any(a => !(bool)a));
From your input I got this:
Upvotes: 2
Reputation: 21795
First of all you need to set the namespace for your XML file like this:-
XNamespace ns = "http://test.net/schema/session/1.0";
I will start looking into descendants of download
because I need to find the result
element which contains the success
attribute (whose value we want to check). Thus, a simple where condition will filter those nodes for us and finally we can select the message
node.
Update:
You can use Concat
if you want to search both download & upload like this:-
IEnumerable<XElement> result = xdoc.Descendants(ns + "download")
.Concat(xdoc.Descendants(ns + "upload"))
.Where(x => x.Element(ns + "result") != null &&
(string)x.Element(ns + "result").Attribute("success") == "false")
.Select(x => x.Element(ns +"result").Element(ns +"message"));
I am also checking in the where clause if result node exist or not by checking for null, otherwise it may result in Null reference exception.
Upvotes: 1
Reputation: 7870
Using some XPath, the following piece of code should work
string xml = @"<session xmlns=""http://test.net/schema/session/1.0"" name=""test"" start=""2015-07-01T07:20:31.425Z"">
<download>
<filename value=""/UAT/Incoming/ Status/Archive/8-22-2011 3-20-14 PM306.xml"" />
<result success=""false"">
<message>Timeout waiting .</message>
</result>
</download>
</session>";
XmlDocument xdoc = new XmlDocument();
xdoc.LoadXml(xml);
// Here, you load the namespace used in your xml. You'll need it later in your XPath queries
XmlNamespaceManager nsmgr = new XmlNamespaceManager(xdoc.NameTable);
nsmgr.AddNamespace("test", "http://test.net/schema/session/1.0");
// XPath to select the "result" node whose attribute "success" equals false
XmlElement xelt = xdoc.DocumentElement.SelectSingleNode("descendant::test:download/test:result[@success=\"false\"]", nsmgr) as XmlElement;
// return the "message" node
return xelt.FirstChild as XmlElement;
As already mentioned, you'll find more details about XPath expression on this link: https://msdn.microsoft.com/en-us/library/d271ytdx%28v=vs.110%29.aspx
Upvotes: 0
Reputation: 31
XDocument doc = XDocument.Load("your xml file path");
var result = doc.Elements().
First(e => e.Name == "download")
.Elements().First(e => e.Name == "result");
if (result.Attributes().First(a => a.Name == "success").Value == "false")
return result.Elements().First(e => e.Name == "message").Value;
Upvotes: 3