C#Linq2XML从子元素值获取父属性

时间:2018-02-24 14:02:22

标签: c# xml linq selectnodes

我关闭了我的最后一个问题,因为它被评论说没有做足够的研究。我研究的越多,我就越困惑。我认为应该在我的理解中以及从这里和其他地方的帖子起作用不起作用。

XML sample
<?xml version="1.0" encoding="UTF-8" ?>
        <multistatus xmlns="DAV:">
        <schmeata>
            <classschema name="Space">                  
                <base_class>Space</base_class>
            </classschema>
            <classschema name="Tapestry">       
                <base_class>File</base_class>
            </classschema>
            <classschema name="Document">       
                <base_class>File</base_class>
            </classschema>
        </schmeata>
        </multistatus>

我正在尝试获取具有“File”值的base_class子类的classschema节点的name属性。所以结果应该是'Tapestry'和'Document'

我可以使用

轻松返回所有classschemata节点
foreach (XmlNode node in xmlDoc.SelectNodes("//DAV:schemata/DAV:classschema", nsmgr))               
            {
                    strNode = node.Attributes["name"].Value;                       
                    responseString += strNode +" ";                   
            }
            return responseString;

我可以通过循环遍历所有base_class节点来获取base_class值='File'。

foreach (XmlNode node in xmlDoc.SelectNodes("//DAV:schemata/DAV:classschema/DAV:base_class", nsmgr))              
            {                    
                if (node.InnerText == "File")
                {                     
                    strNode = node.InnerText;
                    responseString += strNode +" ";
                }                  
            }
            return responseString;

但是如果我尝试过滤或使用axis来引用孩子的父节点,那我就失败了。

我的过滤工作的一个示例基于SelectNodes方法。

foreach (XmlNode node in xmlDoc.SelectNodes("//DAV:schemata/DAV:classschema[/DAV:base_class(contains,'File')]", nsmgr))  or

foreach(xmlDoc.SelectNodes中的XmlNode节点(“// DAV:schemata / DAV:classschema [/ DAV:base_class =='File']”,nsmgr))

以及许多其他变体作为我看到的例子很难说它是LINQ2XML还是XDocument并混合用于PHP或其他语言并不总是指定我现在已经成熟了。

我的下一次尝试将是SelectNodes(“// DAV:schemata / DAV:classschemata [/ DAV:baseclass(contains,'File')]”@ name,nsmgr); 和变化。

我从其他例子中想到,他们完全符合我的要求,但实施后却无法解释,原因我无法解释。

1 个答案:

答案 0 :(得分:0)

这应该会给你你想要的结果。基本上,它会查找具有classschema的第一个元素的所有Value == "File"元素,然后选择其name属性Value。请注意我也使用string.Join方法(对于这样的东西非常方便)将结果转换为空格分隔的字符串,这是你需要的。

var xmlDoc = XDocument.Load("YourFile.xml");

var result = xmlDoc.Descendants("{DAV:}classschema")
    .Where(x => x.Elements().First().Value == "File")
    .Attributes("name")
    .Select(x => x.Value);

string spaceDelimited = string.Join(" ", result);