遍历 XML 个元素的列表
Iterating through a list of XML Elements
我想对之前提出的问题进行跟进,但显然我不能在同一个线程中继续这个问题。
在我之前的问题 () 中,我正在寻找 xml 中所有 url 的值。但是在同一节点内访问不同值的正确方法是什么?
一个例子:
<list index="1" name="" title="" id="5702f74a-9df2-12e5-89e0-f947f6dd0a1f">
<theme>
<properties>
<field index="1"/>
<field index="2" name="title"></field>
</properties>
<list>
<item id="f391fada-90c5-f239-a836-25ca76311286">
<field index="1">
<url>49e424a8ae1bf4707bf4d27c4614e905.png</url>
<title></title>
</field>
<field index="2" name="question">This is a question</field>
<field index="3" name="answer">This is an answer</field>
<field index="4" name="remark"/>
<field index="5" name="reveal"/>
</item>
<item id="a0b97163-d195-4dce-b970-ecb6eb080403">
<field index="1">
<url>49e424a8ae1bf4707bf4d27c4614e905.png</url>
<title></title>
</field>
<field index="2" name="question"/>
<field index="3" name="answer"></field>
<field index="4" name="remark"/>
<field index="5" name="reveal"/>
</item>
</list>
</theme>
</list>
我想逐条阅读这个 XML(在 XML 中逐条阅读)并将具有特定名称的字段的值存储到变量中:
例如:
string url = [value of field URL];
string question= [value of field with name question];
string answer= [value of field with name answer];
string remark= [value of field with name remark];
string reveal= [value of field with name reveal];
我是否必须为每个变量使用类似查询的查询?
var string = xmlDoc.Descendants("list")
.Where(e => (int)e.Attribute("index") == 1)
.Descendants("item").Descendants("field")
.Where(e => (string)e.Attribute("index") == "1")
.Select(e => (string)e.Value());
或者有没有办法获取某种列表中的字段,然后我可以通过它的索引号进行搜索?
foreach (field in fields)
{
switch case (field.name)
{
case "question":
question = field.value;
break;
case "answer":
answer= field.value;
break;
}
}
非常感谢任何想法。
我会创建一个辅助方法来将字段解析为包含所有属性的 Item
对象,并像这样使用它:
var items = from item in doc.Descendants("item")
let fields = item.Elements("field")
select ItemFromFields(fields);
辅助方法会打开字段索引,您可以这样实现:
private static Item ItemFromFields(IEnumerable<XElement> fields)
{
var item = new Item();
foreach (var field in fields)
{
var index = (int)field.Attribute("index");
switch (index)
{
case 1:
item.Url = (string)field.Element("url");
break;
case 2:
item.Question = field.Value;
break;
case 3:
item.Answer = field.Value;
break;
case 4:
item.Remark = field.Value;
break;
case 5:
item.Reveal = field.Value;
break;
}
}
return item;
}
为了完整起见,Item
看起来像这样:
public class Item
{
public string Url { get; set; }
public string Question { get; set; }
public string Answer { get; set; }
public string Remark { get; set; }
public string Reveal { get; set; }
}
试试这个。 URL 字段不包含名称或索引标签,因此您必须测试名称标签是否不等于 null。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
string input =
"<list index=\"1\" name=\"\" title=\"\" id=\"5702f74a-9df2-12e5-89e0-f947f6dd0a1f\">\n" +
"<theme>\n" +
"<properties>\n" +
"<field index=\"1\"/>\n" +
"<field index=\"2\" name=\"title\"></field>\n" +
"</properties>\n" +
"<list>\n" +
"<item id=\"f391fada-90c5-f239-a836-25ca76311286\">\n" +
"<field index=\"1\">\n" +
"<url>49e424a8ae1bf4707bf4d27c4614e905.png</url>\n" +
"<title></title>\n" +
"</field>\n" +
"<field index=\"2\" name=\"question\">This is a question</field>\n" +
"<field index=\"3\" name=\"answer\">This is an answer</field>\n" +
"<field index=\"4\" name=\"remark\"/>\n" +
"<field index=\"5\" name=\"reveal\"/>\n" +
"</item>\n" +
"<item id=\"a0b97163-d195-4dce-b970-ecb6eb080403\">\n" +
"<field index=\"1\">\n" +
"<url>49e424a8ae1bf4707bf4d27c4614e905.png</url>\n" +
"<title></title>\n" +
"</field>\n" +
"<field index=\"2\" name=\"question\"/>\n" +
"<field index=\"3\" name=\"answer\"></field>\n" +
"<field index=\"4\" name=\"remark\"/>\n" +
"<field index=\"5\" name=\"reveal\"/>\n" +
"</item>\n" +
"</list>\n" +
"</theme>\n" +
"</list>\n";
XDocument doc = XDocument.Parse(input);
var results = doc.Descendants("item")
.Select(w => new {
url = w.Descendants("url").FirstOrDefault().Value,
question = w.Descendants("field").Where(x => x.Attribute("name") != null).Where(y => y.Attribute("name").Value == "question").Select(z => z.Attribute("index").Value).FirstOrDefault(),
answer = w.Descendants("field").Where(x => x.Attribute("name") != null).Where(y => y.Attribute("name").Value == "answer").Select(z => z.Attribute("index").Value).FirstOrDefault(),
remark = w.Descendants("field").Where(x => x.Attribute("name") != null).Where(y => y.Attribute("name").Value == "remark").Select(z => z.Attribute("index").Value).FirstOrDefault(),
reveal = w.Descendants("field").Where(x => x.Attribute("name") != null).Where(y => y.Attribute("name").Value == "reveal").Select(z => z.Attribute("index").Value).FirstOrDefault()
})
.ToList();
}
}
}
我想对之前提出的问题进行跟进,但显然我不能在同一个线程中继续这个问题。
在我之前的问题 (
<list index="1" name="" title="" id="5702f74a-9df2-12e5-89e0-f947f6dd0a1f">
<theme>
<properties>
<field index="1"/>
<field index="2" name="title"></field>
</properties>
<list>
<item id="f391fada-90c5-f239-a836-25ca76311286">
<field index="1">
<url>49e424a8ae1bf4707bf4d27c4614e905.png</url>
<title></title>
</field>
<field index="2" name="question">This is a question</field>
<field index="3" name="answer">This is an answer</field>
<field index="4" name="remark"/>
<field index="5" name="reveal"/>
</item>
<item id="a0b97163-d195-4dce-b970-ecb6eb080403">
<field index="1">
<url>49e424a8ae1bf4707bf4d27c4614e905.png</url>
<title></title>
</field>
<field index="2" name="question"/>
<field index="3" name="answer"></field>
<field index="4" name="remark"/>
<field index="5" name="reveal"/>
</item>
</list>
</theme>
</list>
我想逐条阅读这个 XML(在 XML 中逐条阅读)并将具有特定名称的字段的值存储到变量中: 例如:
string url = [value of field URL];
string question= [value of field with name question];
string answer= [value of field with name answer];
string remark= [value of field with name remark];
string reveal= [value of field with name reveal];
我是否必须为每个变量使用类似查询的查询?
var string = xmlDoc.Descendants("list")
.Where(e => (int)e.Attribute("index") == 1)
.Descendants("item").Descendants("field")
.Where(e => (string)e.Attribute("index") == "1")
.Select(e => (string)e.Value());
或者有没有办法获取某种列表中的字段,然后我可以通过它的索引号进行搜索?
foreach (field in fields)
{
switch case (field.name)
{
case "question":
question = field.value;
break;
case "answer":
answer= field.value;
break;
}
}
非常感谢任何想法。
我会创建一个辅助方法来将字段解析为包含所有属性的 Item
对象,并像这样使用它:
var items = from item in doc.Descendants("item")
let fields = item.Elements("field")
select ItemFromFields(fields);
辅助方法会打开字段索引,您可以这样实现:
private static Item ItemFromFields(IEnumerable<XElement> fields)
{
var item = new Item();
foreach (var field in fields)
{
var index = (int)field.Attribute("index");
switch (index)
{
case 1:
item.Url = (string)field.Element("url");
break;
case 2:
item.Question = field.Value;
break;
case 3:
item.Answer = field.Value;
break;
case 4:
item.Remark = field.Value;
break;
case 5:
item.Reveal = field.Value;
break;
}
}
return item;
}
为了完整起见,Item
看起来像这样:
public class Item
{
public string Url { get; set; }
public string Question { get; set; }
public string Answer { get; set; }
public string Remark { get; set; }
public string Reveal { get; set; }
}
试试这个。 URL 字段不包含名称或索引标签,因此您必须测试名称标签是否不等于 null。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
string input =
"<list index=\"1\" name=\"\" title=\"\" id=\"5702f74a-9df2-12e5-89e0-f947f6dd0a1f\">\n" +
"<theme>\n" +
"<properties>\n" +
"<field index=\"1\"/>\n" +
"<field index=\"2\" name=\"title\"></field>\n" +
"</properties>\n" +
"<list>\n" +
"<item id=\"f391fada-90c5-f239-a836-25ca76311286\">\n" +
"<field index=\"1\">\n" +
"<url>49e424a8ae1bf4707bf4d27c4614e905.png</url>\n" +
"<title></title>\n" +
"</field>\n" +
"<field index=\"2\" name=\"question\">This is a question</field>\n" +
"<field index=\"3\" name=\"answer\">This is an answer</field>\n" +
"<field index=\"4\" name=\"remark\"/>\n" +
"<field index=\"5\" name=\"reveal\"/>\n" +
"</item>\n" +
"<item id=\"a0b97163-d195-4dce-b970-ecb6eb080403\">\n" +
"<field index=\"1\">\n" +
"<url>49e424a8ae1bf4707bf4d27c4614e905.png</url>\n" +
"<title></title>\n" +
"</field>\n" +
"<field index=\"2\" name=\"question\"/>\n" +
"<field index=\"3\" name=\"answer\"></field>\n" +
"<field index=\"4\" name=\"remark\"/>\n" +
"<field index=\"5\" name=\"reveal\"/>\n" +
"</item>\n" +
"</list>\n" +
"</theme>\n" +
"</list>\n";
XDocument doc = XDocument.Parse(input);
var results = doc.Descendants("item")
.Select(w => new {
url = w.Descendants("url").FirstOrDefault().Value,
question = w.Descendants("field").Where(x => x.Attribute("name") != null).Where(y => y.Attribute("name").Value == "question").Select(z => z.Attribute("index").Value).FirstOrDefault(),
answer = w.Descendants("field").Where(x => x.Attribute("name") != null).Where(y => y.Attribute("name").Value == "answer").Select(z => z.Attribute("index").Value).FirstOrDefault(),
remark = w.Descendants("field").Where(x => x.Attribute("name") != null).Where(y => y.Attribute("name").Value == "remark").Select(z => z.Attribute("index").Value).FirstOrDefault(),
reveal = w.Descendants("field").Where(x => x.Attribute("name") != null).Where(y => y.Attribute("name").Value == "reveal").Select(z => z.Attribute("index").Value).FirstOrDefault()
})
.ToList();
}
}
}