[英]XDocument: How to find an attribute value in nested xml
Given the working code snippet below, I'm trying to get the target
element inside RootChild2
.鉴于下面的工作代码片段,我试图在
RootChild2
获取target
元素。
https://dotnetfiddle.net/eN4xV9 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");
}
This finds all 3 RootChild2/Child
elements, then tests each in turn:这会找到所有 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");
}
There are three problems here:这里存在三个问题:
RootChild2
element has any attributes - and it doesn'tRootChild2
元素是否具有任何属性 - 但它没有Child
element under each RootChild2
elementRootChild2
元素下的第一个Child
元素XAttribute
)XAttribute
) Here's code which will find all the target elements within a RootChild2
:这是将在
RootChild2
查找所有目标元素的RootChild2
:
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}");
}
}
Note that the cast of XAttribute
to string
is a simple way of avoiding null reference issues - because the result of the explicit conversion is null when the source is null.请注意,将
XAttribute
为string
是一种避免空引用问题的简单方法 - 因为当源为空时,显式转换的结果为空。 (That's a general pattern in LINQ to XML.) (这是 LINQ to XML 中的一般模式。)
You are accessing the RootChild2-Element itself through element
inside your loop.您是通过访问RootChild2-元素本身
element
的循环中。 Take a look at the following version:看看下面的版本:
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");
}
Now it loops through all nodes of RootChild2.现在它循环遍历 RootChild2 的所有节点。
You should rewrite your foreach
loop at little bit, add accessing of child Elements()
collection in RootChild2
and check every element in enumeration.您应该稍微重写您的
foreach
循环,在RootChild2
添加对 child Elements()
集合的RootChild2
并检查枚举中的每个元素。 You also can check that key
attribute is present in element to prevent a potential null reference exception您还可以检查元素中是否存在
key
属性以防止潜在的空引用异常
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");
}
Descendants(XName)
returns only elements with matching names, therefore you are getting only one RootChild2
element as the result in your code Descendants(XName)
仅返回具有匹配名称的元素,因此您在代码中仅获得一个RootChild2
元素作为结果
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.