-1

I'm trying to parse the XML below:

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

This is my parser:

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

Please see the comment that I have added in the XML file. The issue here is that the first two dicts have key as SubTitle with array but the third dict does not have any key.

How should I parse this?

I am working on windows Phone 8 and am trying to parse the XML and populate the data in a UI. This is what my UI looks like: I have 3 buttons: Science, Physics and Random.

When I click on “Science” I get “Chapter one and chapter two”; if I click on either chapter one or chapter two I get all values from the XML.

But when I click on “Random” I need to get only values from the XML.

EDIT

to print values:

foreach (var value in plistData)
{
    topicList.Add(value.Key);
    Debug.WriteLine(" Main title is "+value.Key);
    if (!value.Key.Equals("Random Values"))
    {
        List<Topic> listOfSubTopics = plistData[value.Key];
        for (int j = 0; j < listOfSubTopics.Count; j++)
        {
            Debug.WriteLine("sub title " + listOfSubTopics[j].Title);
            for (int i = 0; i < listOfSubTopics[j].FileNames.Count; i++)
            {
                Debug.WriteLine("Values is" + listOfSubTopics[j].FileNames[i]);
            }
        }
    }
    else
    {
       // here i want to print values of Random Values
    }
Yael
  • 1,566
  • 3
  • 18
  • 25
user2056563
  • 600
  • 2
  • 12
  • 37
  • Please take the time to carefully explain what you are trying to do and what is going wrong. Your question so far seems somewhat unclear and I don't really understand it. – Sheridan Apr 25 '14 at 11:02
  • @Sheridan Can you please invite me to chat room i can explain you – user2056563 Apr 25 '14 at 11:07
  • @Sheridan Can you please join here http://chat.stackoverflow.com/rooms/7/c – user2056563 Apr 25 '14 at 11:13
  • 1
    My request was made to help anyone answer your question, not just me. Therefore, can you please add whatever relevant information that you have to your question where everyone can see it? – Sheridan Apr 25 '14 at 11:32
  • @Sheridan yes you are correct, i have added all info that i have , if any thing specific please ask – user2056563 Apr 25 '14 at 11:33
  • The info you added *before* I requested that you clarify your question *clearly* didn't help, because you added that *before* I requested that you clarify your question. However, it's up to you... if you think that you have provided enough information, then fair enough, but I can't help you from that information. You start talking about parsing XML and then you're talking about `Button`s... *you* may know what you're talking about, but I certainly don't because I don't know anything about your application other than the few scraps of information that you provided here. – Sheridan Apr 25 '14 at 11:37
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/51423/discussion-between-user2056563-and-sheridan) – user2056563 Apr 25 '14 at 11:38
  • Perhaps you should read the [How do I ask a good question?](http://stackoverflow.com/help/how-to-ask) page from the Help Center to find out how to ask a good question? Just to be clear, I don't have the time or inclination to help you ask a proper question... that's your job. *If* you do provide enough information for me to help, then I'll see if I can help... otherwise, I'm simply not interested. – Sheridan Apr 25 '14 at 11:38
  • Your question is a bit clearer now, so well done for that. However, I fail to understand why you want to manually parse this XML, rather than using the functionality that .NET provides you with. You could convert this whole XML file into .NET classes that can be automatically generated for you in just a few lines of code. Please see the [C# - Convert XML String to Object](http://stackoverflow.com/questions/3187444/c-sharp-convert-xml-string-to-object) question here for a wonderful description of how to do this if you're interested. – Sheridan Apr 25 '14 at 14:57
  • @Sheridan Now with the answer from `Rene` i am able to get values of Science and Physics but i want to print values of Random values from the xml how will i do that ? – user2056563 Apr 25 '14 at 15:00

1 Answers1

1

For debugging purposes I split your collection in two steps:

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

Helper for the last plist structure

    static List<Chapter> ParseMyString(XElement dict)
    {

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

I added a check when you create the dictionary element if the key MainTitle actually exists. If it doesn't I add a default key. The same mechanism is applied to SubTitle, if that doesn't exist a null value is supplied.

rene
  • 41,474
  • 78
  • 114
  • 152
  • 1
    No, I can't provide full code. I fixed what I believe was wrong based on your vague question. It is not that hard to replace the few lines in your code with my code. Ask a new question instead but remember we are not here to do your work. – rene Apr 25 '14 at 13:33
  • i got it sorry for the above comment, if there is no main title i want the title and main title to be `Random Values` can we modify ? and also the `Random Values` should contain the `Values` in it – user2056563 Apr 25 '14 at 13:38
  • One last question i am trying to print the values i am able to get the `Chapter One and two` of `physics and science` but how can i print the values `Random Values` `CD1,CD2,DDC1,DDC2,DC1 and DC2` ? – user2056563 Apr 25 '14 at 14:24
  • Can you please help me here http://stackoverflow.com/questions/24161008/coverflow-with-out-of-memory – user2056563 Jun 11 '14 at 10:54