C# 识字LINQ到XML:将属性/值反序列化为结构化变量/值对的最佳实践

C# 识字LINQ到XML:将属性/值反序列化为结构化变量/值对的最佳实践,c#,serialization,linq-to-xml,C#,Serialization,Linq To Xml,我正在努力反序列化以下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" seve

我正在努力反序列化以下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>
我知道我完全没有抓住要点,不仅因为我在这里重复了很多,而且因为只有一个项目时查询才起作用。同样,如果您有任何意见或建议,我们将不胜感激。 非常感谢

更新:如果前一个例子没有真正的帮助,下面是一个更现实的场景:

<?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>

通常我希望每个元素都有一个表示,而不是一个“一”值序列和另一个“两”值序列。换言之,我期望的是:

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");
var items = config.Descendants("item")
                  .Select(element => Item.FromXElement(element));
public static Item FromXElement(XElement element)
{
    string name = (string) element.Attribute("name");
    string host = (string) element.Attribute("host");
    // etc
    return new Item(name, host, ...);
}
如果在单个元素中有很多属性,我发现将“从该元素生成对象”代码分离到它自己的方法(在本例中为
Item.FromXElement
)而不是将其全部填充到查询中会很有帮助。如果
Item
不应该知道它的LINQ到XML表示,请将该方法放在应该的地方:)

items
则是一个
IEnumerable
,您可以将其转换为列表或任何您想要执行的操作

当然,这真的取决于你想做什么——我们真的不知道这意味着什么。也许你真的想要每个“属性序列”分开


Item.FromXElement
看起来像:

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");
var items = config.Descendants("item")
                  .Select(element => Item.FromXElement(element));
public static Item FromXElement(XElement element)
{
    string name = (string) element.Attribute("name");
    string host = (string) element.Attribute("host");
    // etc
    return new Item(name, host, ...);
}
(显然,您应该使用适当的参数创建构造函数。)

我会这样做:

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);

首先非常感谢你的评论,Jon!我真的需要把这些分开;假设我正在坚持,比方说,连接细节或书签,等等,那么就要让lorem和ipsum元素分开,然后从属性中创建键/值对。我希望你遵循了我的阐述,无论如何,请不要犹豫,要求我做进一步的解释:)我真的不遵循阐述,不。你能编辑你的问题,给出一个更完整的例子,说明你正在尝试做什么,以及你以后想如何使用这些信息吗?我做了。提前多谢了,乔恩。对了——看起来每个项目都有一堆信息。我将创建适当的对象,将所有这些对象放在一起,并列出这些对象。关于如何实现项的任何想法。FromXElement序列化魔术?Pavel非常感谢您的评论,尽管我真正需要的是有两个结果集合isis和seth,它们都具有可访问的所有属性,可能以isis.host、isis.user等形式。