XDocument:如何在嵌套的xml中查找属性值

问题描述 投票:0回答:2

鉴于下面的工作代码段,我正在尝试在target中获取RootChild2元素。

https://dotnetfiddle.net/eN4xV9

string str =
    @"<?xml version=""1.0""?>  
    <!-- comment at the root level -->  
    <Root>  
        <RootChild1>
            <Child>Content</Child>  
            <Child>Content</Child>  
            <Child>Content</Child>  
        </RootChild1>
        <RootChild2>
            <Child>Content</Child>  
            <Child key='target'>Content</Child>  
            <Child>Content</Child>  
        </RootChild2>
    </Root>";
XDocument doc = XDocument.Parse(str);

foreach (XElement element in doc.Descendants("RootChild2"))
{
    if (element.HasAttributes && element.Element("Child").Attribute("key").Value == "target")
        Console.WriteLine("found it");
    else
        Console.WriteLine("not found");
}
c# xml linq-to-xml
2个回答
0
投票

这里有三个问题:

  • 您正在检查RootChild2元素是否具有任何属性-并没有
  • 您仅检查每个Child元素下的第一个RootChild2元素
  • 您是假设该属性存在(通过取消引用XAttribute

这里的代码将在RootChild2中找到all目标元素:

foreach (XElement element in doc.Descendants("RootChild2"))
{
    var targets = element
        .Elements("Child")
        .Where(child => (string) child.Attribute("key") == "target")
        .ToList();
    Console.WriteLine($"Found {targets.Count} targets");
    foreach (var target in targets)
    {
        Console.WriteLine($"Target content: {target.Value}");
    }            
}

请注意,将XAttribute强制转换为string是避免空引用问题的一种简单方法-因为当源为null时,显式转换的结果为null。 (这是LINQ to XML中的通用模式。)


0
投票

您正在通过循环内的element访问RootChild2-Element本身。看看以下版本:

        foreach (XElement element in doc.Descendants("RootChild2").Nodes())
        {
            if (element.HasAttributes && element.Attribute("key").Value == "target")
                Console.WriteLine("found it");
            else
                Console.WriteLine("not found");
        }

现在,它遍历RootChild2的所有节点。


0
投票

一点点重写foreach循环并添加空检查

foreach (XElement element in doc.Descendants("RootChild2").Elements())
{
    if (element.HasAttributes && element.Attribute("key")?.Value == "target")
        Console.WriteLine("found it");
    else
        Console.WriteLine("not found");
}

0
投票

这将找到所有3个RootChild2/Child元素,然后依次测试每个元素:

        foreach (XElement child in doc.Descendants("RootChild2").Elements("Child"))
        {
            if ((string)child.Attribute("key") == "target")
                Console.WriteLine("found it");
            else
                Console.WriteLine("not found");
        }
© www.soinside.com 2019 - 2024. All rights reserved.