我是LINQ to XML的新手,并且想知道是否有人可以帮我构建以下查询。
我想返回所有不包含含有“404”的后代<response>
元素的<status>
元素。
我的XML如下所示。在这种情况下,只应返回第一个<response>
元素(和后代)。
<multistatus xmlns="DAV:">
<response>
<href>/principals/users/test/</href>
<propstat>
<prop>
<calendar-home-set xmlns="urn:ietf:params:xml:ns:caldav">
<href xmlns="DAV:">/calendars/__uids__/d817aaec-7d24-5b38-bc2f-6369da72cdd9</href>
</calendar-home-set>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
<response>
<href>/principals/users/test/calendar-proxy-write/</href>
<propstat>
<prop>
<calendar-home-set xmlns="urn:ietf:params:xml:ns:caldav" />
</prop>
<status>HTTP/1.1 404 Not Found</status>
</propstat>
</response>
<response>
<href>/principals/users/test/calendar-proxy-read/</href>
<propstat>
<prop>
<calendar-home-set xmlns="urn:ietf:params:xml:ns:caldav" />
</prop>
<status>HTTP/1.1 404 Not Found</status>
</propstat>
</response>
</multistatus>
答案 0 :(得分:3)
假设您的XML存储在字符串变量xml
中:
XDocument document = XDocument.Parse(xml);
XNamespace ns = document.Root.GetDefaultNamespace();
var responsesExcept404s = document
.Descendants(ns + "response")
.Where(x => !x.Descendants(ns + "status")
.Single()
.Value.Contains("404"));
注意ns
变量的用法 - 因为您的XML具有通过xmlns
属性设置的默认命名空间,所以在使用LINQ to XML时必须指定该命名空间(例如在Descendants()
中法)。
然后你可以简单地迭代结果,为了使它超级有用,将它们输出到控制台:
responsesExcept404s.ToList().ForEach(Console.WriteLine);
答案 1 :(得分:2)
XDocument xDoc = XDocument.Parse(xml);
XNamespace ns = XNamespace.Get("DAV:");
var responses = xDoc.Descendants(ns + "status")
.Where(s => !s.Value.Contains(" 404 "))
.Select(s => s.Parent.Parent);
答案 2 :(得分:1)
这里你去:(与XPath作弊)
XDocument xdoc = XDocument.Load(new FileStream("XMLFile2.xml", FileMode.Open, FileAccess.Read));
XPathNavigator nav = xdoc.CreateNavigator();
var nsm = new XmlNamespaceManager(nav.NameTable);
nsm.AddNamespace("s", "DAV:");
var nodes = xdoc.XPathSelectElements("s:multistatus/s:response[.//*[name(.)='status' and .='HTTP/1.1 404 Not Found']]", nsm);
答案 3 :(得分:0)
试试这个:
Document doc = XDocument.Load(path);
XNamespace nsd = doc.Root.GetDefaultNamespace();
var res = doc.Descendants(nsd +"response");
var filteredEle = new List<XElement>();
foreach (var ele in res)
{
if (CheckEle(ele,nsd))
{
filteredEle.Add(ele);
}
}
private bool CheckEle(XElement ele, XNamespace nsd)
{
return ele.Element(nsd + "propstat").Element(nsd + "status").Value != "HTTP/1.1 404 Not Found";
}
答案 4 :(得分:0)
您可以使用如下所示的linq语句
XDocument doc = XDocument.Parse(xml);
List<XElement> responseWithOut404 =
(from element in doc.Descendants("response")
let xElement = element.Descendants("status").First()
where !xElement.Value.Contains("404")
select element)
.ToList();