使用不同的密钥解析xml

时间:2014-04-25 10:50:44

标签: c# wpf windows-phone-8 xml-parsing linq-to-xml

我试图解析下面的XML:

<plist version="1.0">
<array>
    <dict>
        <key>SubTitle</key>
        <array>
            <dict>
                <key>Values</key>
                <array>
                    <string>D1</string>
                    <string>D2</string>
                </array>
                <key>Title</key>
                <string>Chapter One</string>
                <key>supportsEdit</key>
                <true/>
            </dict>
            <dict>
                <key>Values</key>
                <array>
                    <string>DC1</string>
                    <string>DC2</string>
                </array>
                <key>Title</key>
                <string>Chapter Two</string>
                <key>supportsEdit</key>
                <true/>
            </dict>
        </array>
        <key>MainTitle</key>
        <string>Science</string>
    </dict>
    <dict>
        <key>SubTitle</key>
        <array>
            <dict>
                <key>Values</key>
                <array>
                    <string>CD1</string>
                    <string>CD2</string>
                </array>
                <key>Title</key>
                <string>Chapter One</string>
                <key>supportsEdit</key>
                <true/>
            </dict>
            <dict>
                <key>Values</key>
                <array>
                    <string>DDC1</string>
                    <string>DDC2</string>
                </array>
                <key>Title</key>
                <string>Chapter Two</string>
                <key>supportsEdit</key>
                <true/>
            </dict>
        </array>
        <key>MainTitle</key>
        <string>Physics</string>
    </dict>

    /// here is where i get the error
    <dict>
        <key>Values</key>
        <array>
                            <string>CD1</string>
                <string>CD2</string>
                            <string>DDC1</string>
            <string>DDC2</string>
                            <string>DC1</string>
                        <string>DC2</string>
        </array>
        <key>Title</key>
        <string>Random Values</string>
        <key>supportsEdit</key>
        <true/>
    </dict>

这是我的解析器:

XDocument doc = XDocument.Load(FileName);

Dictionary<string, List<Chapter>> plistData =
        doc.Root.Element("array").Elements("dict")
            .Select(GetValues)
            .ToDictionary(v => (string)v["MainTitle"],
                          v => v["SubTitle"]
                          .Elements("dict").Select(ParseMyObject).ToList());

static Dictionary<string, XElement> GetValues(XElement dict)
{
    return dict.Elements("key")
               .ToDictionary(k => (string)k, k => (XElement)k.NextNode);
}

static Chapter ParseMyObject(XElement dict)
{
    var values = GetValues(dict);

    return new Topic
    {
        Title = (string)values["Title"],
        FileNames = values["Values"].Elements().Select(s =>(string)s).ToList()
    };
}

请参阅我在XML文件中添加的评论。这里的问题是,前两个dict的{​​{1}} keySubTitle,而array的{​​{1}}没有任何dict

我应该如何解析这个?

我正在使用Windows Phone 8,我正在尝试解析XML并在UI中填充数据。这就是我的用户界面:我有3个按钮:科学,物理和随机。

当我点击“科学”时,我得到“第一章和第二章”;如果我点击第一章或第二章,我将从XML获得所有值。

但是当我点击“随机”时,我只需要从XML中获取值。

编辑

打印值:

key

1 个答案:

答案 0 :(得分:1)

出于调试目的,我分两步拆分你的收藏:

        var first = doc
            .Root
            .Element("array")
            .Elements("dict")
            .Select(GetValues);

       var plistData = first
            .ToDictionary(
                v => v.ContainsKey("MainTitle")?
                        (string) v["MainTitle"]:
                        (string) v["Title"],
                 v => (v.ContainsKey("SubTitle")?
                        v["SubTitle"]
                        .Elements("dict")
                        .Select(ParseMyObject) :
                        ParseMyString(v["Values"])
                        )
                        .ToList());

最后一个plist结构的助手

    static List<Chapter> ParseMyString(XElement dict)
    {

        return new List<Chapter>
            {
                new Chapter
                    {
                        Title = "some values",
                        FileNames = dict.Elements().Select(s => (string) s).ToList()
                    }
            };
    } 

如果密钥 MainTitle 实际存在,我在创建字典元素时添加了一个检查。如果我没有添加默认密钥。相同的机制适用于 SubTitle ,如果不存在则提供空值。