I'm struggling to navigate to my 'user' element in my XML; I want a set of users so I can then extract username details. My LINQ query is as follows and always returns 0 for the count (though is not null)
var xApprovers = from d in doc.Root.Descendants("document_version")
.Elements("stages")
.Elements("stage")
.Elements("user")
.Elements("approver_list")
.Elements("approver")
.Elements("user")
where d.Element("docVersionID").Value == vId
select d;
My XML source is:
<Root>
<document_version>
<version_number>1</version_number>
<version_comments></version_comments>
<creation_date>2011-12-20 09:20:42.877</creation_date>
<docVersionID>00002_0000000453</docVersionID>
<pageno>-1</pageno>
<author>
<user>
<userID>00002_0000000001</userID>
<login>ACRE_ROBOT</login>
<lastname>ROBOT</lastname>
<firstname>ACRE</firstname>
<email>richardtaylor@vcg-kestrel.com</email>
</user>
</author>
<document_approval_cycle_code>0</document_approval_cycle_code>
<document_approval_cycle_status>Not Started</document_approval_cycle_status>
<stage_index>1</stage_index>
<stages>
<stage>
<stage_id>00002_0000001017</stage_id>
<name></name>
<index>1</index>
<conditional_approval>1</conditional_approval>
<upon_rejection_code>0</upon_rejection_code>
<stage_approval_cycle_code>0</stage_approval_cycle_code>
<stage_approval_cycle_status>Not Started</stage_approval_cycle_status>
<stage_approval_code>00001_0000000002</stage_approval_code>
<stage_approval_status>Pending</stage_approval_status>
<approver_list>
<approver>
<user>
<userID>00002_0000000011</userID>
<login>DEVAPP78@APPROVER.COM</login>
<lastname>App 78</lastname>
<firstname>Dev</firstname>
<email>DevApp78@approver.com</email>
</user>
<approval_action />
</approver>
<approver>
<user>
<userID>00002_0000000010</userID>
<login>DEVAPP77@APPROVER.COM</login>
<lastname>App 77</lastname>
<firstname>Dev</firstname>
<email>DevApp77@approver.com</email>
</user>
<approval_action />
</approver>
</approver_list>
</stage>
</stages>
<approvals></approvals>
</document_version>
</Root>
What am I doing wrong? Thanks in advance.
you have an extra user selection. Try
var xApprovers = from d in doc.Root
.Descendants("document_version")
where d.Element("docVersionID").Value == vId
select d.Elements("stages")
.Elements("stage")
.Elements("approver_list")
.Elements("approver")
.Elements("user");
You had two problems, you had an extra .Elements("user") which wasn't necessary
You also were trying to apply the where clause to the wrong element
Here's the corrected LINQ which returns the result in the same IEnumerable<XElement> as your original
var xGood = from docVersion in doc.Root.Descendants( "document_version" )
where docVersion.Element("docVersionID").Value == vId
from d in docVersion.Elements( "stages" )
.Elements( "stage" )
.Elements( "approver_list" )
.Elements( "approver" )
.Elements( "user" )
select d;
The notable difference between this LINQ and abatishchev's is that this would support multiple document_version nodes in a single xml document
Why don't just this:
from d in doc.Root.Descendants("document_version")
where d.Element("docVersionID").Value == vId
select d.Elements("stages")
.Elements("stage")
.Elements("approver_list")
.Elements("approver")
.Elements("user");
or
doc.Root
.Descendants("document_version")
.SingleOrDefault(d => d.Element("docVersionID").Value == vId).Elements("stages") // sic!
.Elements("stage")
.Elements("approver_list")
.Elements("approver")
.Elements("user");
Or run XPath:
(IEnumerable)doc.XPathEvaluate(String.Format("Root/document_version/docVersionID[text()='{0}']/../stages/stage/approver_list/approver/user", vId));
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.