我正在努力反序列化以下XML:
<?xml version="1.0" encoding="utf-8" ?>
<conf name="settings">
<item name="lorem"
one="the"
two="quick"
three="brown"
four="fox"
five="jumps"
six="over"
seven="the"
eight="lazy"
nine="dog"
/>
<item name="ipsum"
one="how"
two="many"
three="roads"
four="must"
five="a"
six="man"
seven="walk"
eight="down"
nine="?"
/>
</conf>
希望以最优雅和简洁的方式使用LINQ-to-XML这样做,但考虑到我不是城里最聪明的孩子,当谈到嵌套方法,感染类型,泛型,等等,我想如果你们中的任何一个人想继续向我展示一些LINQ读写能力,那将是一个好主意:)
现在我正在做的每件事情都是这样的:
XDocument config = XDocument.Load("whatever.conf");
var one = from q in config.Descendants("item")
select (string)q.Attribute("one");
var two = from q in config.Descendants("item")
select (string)q.Attribute("two");
并且我知道我完全忽略了这一点,不仅因为我在那里重复了很多,而且因为只有当一个项目时,查询才有效,所以,如果你有任何意见或建议,我会非常感激。 非常感谢!
更新:如果前一个示例可能没有真正帮助,这里有一种更现实的场景:
<?xml version="1.0" encoding="utf-8" ?>
<conf name="ftp-settings" freq="daily" time="23:00">
<item name="isis"
host="10.10.1.250"
user="jdoe"
pass="4/cB0kdFGprXR/3oTs8mtw=="
file="backup.tar.gz"
path="/var/log"
/>
<item name="seth"
host="10.10.2.250"
user="jdoe"
pass="4/cB0kdFGprXR/3oTs8mtw=="
file="backup.tar.gz"
path="/var/log"
/>
</conf>
因此,对于每个项目,我都想生成变量,因此我可以将它们作为参数传递给某些FTP管理方法。
解决:
这就像做一个 foreach 一样简单:
var elements = from element in xml.Descendants("item") select element;
foreach (XElement item in elements) {
ftp.DownloadFile(
item.Attribute("host").Value,
item.Attribute("user").Value,
item.Attribute("pass").Value,
item.Attribute("file").Value,
item.Attribute("path").Value
);
}
答案 0 :(得分:3)
通常我希望想要每个元素的单个表示,而不是一个“one”值序列和另一个“two”值序列。换句话说,我希望有类似的东西:
var items = config.Descendants("item")
.Select(element => Item.FromXElement(element));
如果你在一个元素中有很多属性,我发现将“从这个元素中创建一个对象”代码分离到它自己的方法(在这种情况下是Item.FromXElement
)而不是填充它是有帮助的全部进入查询。如果Item
不应该知道它的LINQ to XML表示,那么把方法放在应该的地方:)
items
然后是IEnumerable<Item>
,您可以将其转换为列表或其他任何您想要做的事情。
当然,这实际上取决于你想要做什么 - 我们并不真正知道这意味着什么。也许你真的做分别想要每个“属性序列”...
Item.FromXElement
看起来像:
public static Item FromXElement(XElement element)
{
string name = (string) element.Attribute("name");
string host = (string) element.Attribute("host");
// etc
return new Item(name, host, ...);
}
(显然你可以使用适当的参数创建一个构造函数。)
答案 1 :(得分:1)
我会这样做:
XDocument config = XDocument.Load("whatever.conf");
var pairs = from q in config.Descendants("item")
select new {
One = (string)q.Attribute("one"),
Two = (string)q.Attribute("two") };
var ones = pairs.Select(pair => pair.One);
var twos = pairs.Select(pair => pair.Two);