Select 其兄弟节点具有特定子节点的节点
Select a node the sibling of which has a specific child
这是XML:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<multistatus
xmlns="DAV:">
<response>
<href>/1437425399/carddavhome/</href>
<propstat>
<prop>
<resourcetype>
<collection/>
</resourcetype>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
<response>
<href>/1437425399/carddavhome/card/</href>
<propstat>
<prop>
<resourcetype>
<addressbook
xmlns="urn:ietf:params:xml:ns:carddav"/>
<collection/>
</resourcetype>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
</multistatus>
我想select/1437425399/carddavhome/card/ 其兄弟有子元素。
我尝试了以下方法:
XNamespace nsdav = "DAV:";
XNamespace nscd = "urn:ietf:params:xml:ns:carddav";
var hrefs = from response in root.Elements(nsdav + "response")
where response.Elements(nscd + "addressbook") != null
select response.Element(nsdav + "href");
和
var hrefs = from response in root.Elements(nsdav + "response")
where response.Elements(nscd + "addressbook").Count() > 0
select response.Element(nsdav + "href");
和
var hrefs = (from href in root.Descendants(nsdav + "href")
where href.Parent.Elements(nscd + "addressbook").Count() > 0
select href.Ancestors()).First()
也许还有其他一些类似的逻辑,但无法获得我正在寻找的结果。我哪里错了?
我要么在最终结果中同时获得 标签,要么 none。我希望能够 select 只有一个节点。
**编辑
我不会事先知道 中的文本我想要 select。我唯一知道的是,我必须 select < href > 的文本,其兄弟节点有 < addressbook > 节点作为其子节点。
您可以使用下面的代码
public static XmlNode SelectXmlNode()
{
XmlNode addNode=null;
string xmlString = "*xmlString*"
XmlDocument doc = new XmlDocument();
doc.LoadXml(xmlString);
var node = doc.ChildNodes;
var siblings = node[0].NextSibling.ChildNodes;
foreach (XmlNode cnode in siblings)
{
var childnode = cnode.ChildNodes[0].NextSibling.ChildNodes[0].ChildNodes[0].FirstChild;
if (childnode.Name == "addressbook")
{
addNode = cnode.ChildNodes[0];
}
}
return addNode;
}
好的,所以我终于弄明白了。我的主要问题是检查特定子元素的存在,我使用 null 并为此计数。但是,linq to xml 不是那样工作的。要检查元素是否存在,您必须像这样使用 "Any":
var hrefs = from response in root.Elements(nsdav + "response")
where
(from addressbook in response.Descendants(nscd + "addressbook")
select addressbook)
.Any()
select response.Element(nsdav + "href").Value;
这就是我得到我想要的结果的方式。
这是XML:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<multistatus
xmlns="DAV:">
<response>
<href>/1437425399/carddavhome/</href>
<propstat>
<prop>
<resourcetype>
<collection/>
</resourcetype>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
<response>
<href>/1437425399/carddavhome/card/</href>
<propstat>
<prop>
<resourcetype>
<addressbook
xmlns="urn:ietf:params:xml:ns:carddav"/>
<collection/>
</resourcetype>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
</multistatus>
我想select
我尝试了以下方法:
XNamespace nsdav = "DAV:";
XNamespace nscd = "urn:ietf:params:xml:ns:carddav";
var hrefs = from response in root.Elements(nsdav + "response")
where response.Elements(nscd + "addressbook") != null
select response.Element(nsdav + "href");
和
var hrefs = from response in root.Elements(nsdav + "response")
where response.Elements(nscd + "addressbook").Count() > 0
select response.Element(nsdav + "href");
和
var hrefs = (from href in root.Descendants(nsdav + "href")
where href.Parent.Elements(nscd + "addressbook").Count() > 0
select href.Ancestors()).First()
也许还有其他一些类似的逻辑,但无法获得我正在寻找的结果。我哪里错了?
我要么在最终结果中同时获得
**编辑
我不会事先知道
您可以使用下面的代码
public static XmlNode SelectXmlNode()
{
XmlNode addNode=null;
string xmlString = "*xmlString*"
XmlDocument doc = new XmlDocument();
doc.LoadXml(xmlString);
var node = doc.ChildNodes;
var siblings = node[0].NextSibling.ChildNodes;
foreach (XmlNode cnode in siblings)
{
var childnode = cnode.ChildNodes[0].NextSibling.ChildNodes[0].ChildNodes[0].FirstChild;
if (childnode.Name == "addressbook")
{
addNode = cnode.ChildNodes[0];
}
}
return addNode;
}
好的,所以我终于弄明白了。我的主要问题是检查特定子元素的存在,我使用 null 并为此计数。但是,linq to xml 不是那样工作的。要检查元素是否存在,您必须像这样使用 "Any":
var hrefs = from response in root.Elements(nsdav + "response")
where
(from addressbook in response.Descendants(nscd + "addressbook")
select addressbook)
.Any()
select response.Element(nsdav + "href").Value;
这就是我得到我想要的结果的方式。