英文:
Grab multiple instances of a node
问题
我有一个XML文件块在这里。我想要提取所有ToyId的实例并将其放入一个数组中。同时只提取具有"Hastoys = "YES""属性的节点。
<Bookstore Hastoys="YES">
<Authors>7</Authors>
<Location>Austin TX</Location>
<Employees>15</Employees>
<ToyList>
<ToyId>124</ToyId>
<ToyId>1251</ToyId>
</ToyList>
<ToyList>
<ToyId>255-2</ToyId>
<ToyId>6623</ToyID>
</ToyList>
</Bookstore>
var list = from r in doc.Descendants("Bookstore")
.Where(node => (string)node.Attribute("HasToys") == "YES")
select new
{
ToyId = r.Element("ToyList")?.Element("ToyId")?.Value,
};
我尝试使用上面的查询,但它只返回我ToyId的第一个实例,然后转到下一个块。所以输出将是:124,然后跳过其他ToyId。
英文:
I have a block of an XML file here. I want to grab all the instances of the ToyId and put it in an array. As well as only grab the node with the "Hastoys = "YES"" attribute.
<Bookstore Hastoys="YES">
<Authors>7</Authors>
<Location>Austin TX</Location>
<Employees>15</Employees>
<ToyList>
<ToyId>124</ToyId>
<ToyId>1251</ToyId>
</ToyList>
<ToyList>
<ToyId>255-2</ToyId>
<ToyId>6623</ToyID>
</ToyList>
</Bookstore>
var list = from r in doc.Descendants("Bookstore")
.Where(node => (string)node.Attribute("HasToys") == "YES")
select new
{
ToyId = r.Element("ToyList")?.Element("ToyId")?.Value,
};
I tried using the query above but its only returning me the first instance of toy id then goes to the next block. So the output would be: 124, and skip the other toyids.
答案1
得分: 2
从您的XML中存在一些问题/顾虑:
1. `<ToyId>` 元素的无效闭合标签为
```xml
<ToyId>6623</ToyID>
- 在
Bookstore
元素中的属性为"Hastoys"
<Bookstore Hastoys="YES">
但是您的代码中引用的是 "HasToys"
(string)node.Attribute("HasToys") == "YES"
方法 1
假设您修复了上述提到的问题,使用 .Descendants("ToyList").Elements("ToyId")
获取 ToyList
元素下的每个 ToyId
元素。
string xml = @"<Bookstore HasToys=""YES"">
<Authors>7</Authors>
<Location>Austin TX</Location>
<Employees>15</Employees>
<ToyList>
<ToyId>124</ToyId>
<ToyId>1251</ToyId>
</ToyList>
<ToyList>
<ToyId>255-2</ToyId>
<ToyId>6623</ToyId>
</ToyList>
</Bookstore>";
XDocument doc = XDocument.Parse(xml);
var list = (from r in doc.Descendants("Bookstore")
.Where(node => (string)node.Attribute("HasToys") == "YES")
.Descendants("ToyList")
.Elements("ToyId")
select new
{
ToyId = r.Value,
});
方法 2
您也可以使用 XPath
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
XmlNode root = doc.DocumentElement;
var list = root.SelectNodes("//Bookstore[@HasToys='YES']/ToyList/ToyId").Cast<XmlNode>()
.Select(x => new
{
ToyId = x.InnerText
})
.ToList();
<details>
<summary>英文:</summary>
Few issues/concerns from your XML:
1. Invalid closing tag for
<ToyId>6623</ToyID>
2. The attribute in `Bookstore` element is "Hastoys"
<Bookstore Hastoys="YES">
But your code is referring "HasToys"
(string)node.Attribute("HasToys") == "YES"
**Approach 1**
Assume that you fixed the mentioned issues/concerns, working with `.Descendants("ToyList").Elements("ToyId")` to get each `ToyId` element under the `ToyList` elements.
```csharp
string xml = @"<Bookstore HasToys=""YES"">
<Authors>7</Authors>
<Location>Austin TX</Location>
<Employees>15</Employees>
<ToyList>
<ToyId>124</ToyId>
<ToyId>1251</ToyId>
</ToyList>
<ToyList>
<ToyId>255-2</ToyId>
<ToyId>6623</ToyId>
</ToyList>
</Bookstore>";
XDocument doc = XDocument.Parse(xml);
var list = (from r in doc.Descendants("Bookstore")
.Where(node => (string)node.Attribute("HasToys") == "YES")
.Descendants("ToyList")
.Elements("ToyId")
select new
{
ToyId = r.Value,
});
Approach 2
You may work with XPath as well
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
XmlNode root = doc.DocumentElement;
var list = root.SelectNodes("//Bookstore[@HasToys='YES']/ToyList/ToyId").Cast<XmlNode>()
.Select(x => new
{
ToyId = x.InnerText
})
.ToList();
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论