private PlistDictionary LoadDictionaryContents(XmlReader reader, PlistDictionary dict) { Debug.Assert(reader.NodeType == XmlNodeType.Element && reader.LocalName == "key"); while (!reader.EOF && reader.NodeType == XmlNodeType.Element) { string key = reader.ReadElementString(); while (reader.NodeType != XmlNodeType.Element && reader.Read()) { if (reader.NodeType == XmlNodeType.EndElement) { throw new Exception(String.Format("No value found for key {0}", key)); } } PlistObjectBase result = LoadFromNode(reader); if (result != null) { dict.Add(key, result); } reader.ReadToNextSibling("key"); } return(dict); }
private PlistObjectBase LoadFromNode(XmlReader reader) { Debug.Assert(reader.NodeType == XmlNodeType.Element); bool isEmpty = reader.IsEmptyElement; switch (reader.LocalName) { case "dict": var dict = new PlistDictionary(true); if (!isEmpty) { if (reader.ReadToDescendant("key")) { dict = LoadDictionaryContents(reader, dict); } reader.ReadEndElement(); } return(dict); case "array": if (isEmpty) { return(new PlistArray()); } //advance to first node reader.ReadStartElement(); while (reader.Read() && reader.NodeType != XmlNodeType.Element) { ; } // HACK: plist data in iPods is not even valid in some cases! Way to go Apple! // This hack checks to see if they really meant for this array to be a dict. if (reader.LocalName == "key") { var ret = LoadDictionaryContents(reader, new PlistDictionary(true)); reader.ReadEndElement(); return(ret); } var arr = new PlistArray(); do { if (reader.NodeType == XmlNodeType.Element) { var val = LoadFromNode(reader); if (val != null) { arr.Add(val); } } } while (reader.Read() && reader.NodeType != XmlNodeType.EndElement); reader.ReadEndElement(); return(arr); case "string": return(new PlistString(reader.ReadElementContentAsString())); case "integer": return(new PlistInteger(reader.ReadElementContentAsInt())); case "real": return(new PlistReal(reader.ReadElementContentAsDouble())); case "false": reader.ReadStartElement(); if (!isEmpty) { reader.ReadEndElement(); } return(new PlistBoolean(false)); case "true": reader.ReadStartElement(); if (!isEmpty) { reader.ReadEndElement(); } return(new PlistBoolean(true)); case "data": return(new PlistData(reader.ReadElementContentAsString())); case "date": return(new PlistDate(reader.ReadElementContentAsDateTime())); default: throw new XmlException(String.Format("Plist Node `{0}' is not supported", reader.LocalName)); } }