选择一个其兄弟姐妹具有特定子节点的节点

时间:2018-08-23 02:49:41

标签: c# linq-to-xml

这是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>

我要选择 / 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()

以及其他一些类似的逻辑,但无法获得我想要的结果。我要去哪里错了?

我要么在最终结果中都得到了标签,要么都没有。我希望只能选择一个节点。

**编辑 我不会预先知道我要选择的中的文本。我唯一知道的是,我必须选择的文本,其兄弟具有<地址簿>节点作为其子代。

2 个答案:

答案 0 :(得分:3)

您可以使用以下代码

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;
    }

答案 1 :(得分:0)

好的,所以我终于弄清楚了。我的主要问题是检查是否存在特定的子元素,而我为此使用了null和count。但是,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;

这就是我得到想要的结果的方式。