public static PListDocument LoadFromXml(XmlReader reader)
{
PListDocument document = new PListDocument(true);
// The XML parsing is based on a top-down stack exploration
StringBuilder tempContent = new StringBuilder();
Stack<PListItemBase> stack = new Stack<PListItemBase>();
while (reader.Read())
{
switch (reader.NodeType)
{
case XmlNodeType.Element:
{
String name = reader.Name;
bool empty = reader.IsEmptyElement;
// Collect all the attributes
Dictionary<String, String> attributes = new Dictionary<String, String>();
if (reader.HasAttributes)
{
for (int i = 0; i < reader.AttributeCount; i++)
{
reader.MoveToAttribute(i);
attributes.Add(reader.Name, reader.Value);
}
}
// Create an object corresponding to the node
PListItemBase item = Create(name);
if (String.Equals("plist", name))
{
// The "plist" node has a special treatment
document.Root = item as PList;
}
else
{
// Append the node to the current parent node
PListItemBase current = stack.Peek();
current.AppendChild(item);
}
// Push the new node in the context stack
stack.Push(item);
// Prepare the content collector for node with text
tempContent = new StringBuilder();
// An empty node is pop right-away from the context stack
if (empty)
{
stack.Pop();
item.SetValue(tempContent.ToString());
}
}
break;
case XmlNodeType.EndElement:
{
// When the node ends, it is pop from the context stack and its content is set
PListItemBase item = stack.Pop();
item.SetValue(tempContent.ToString());
}
break;
case XmlNodeType.Text:
case XmlNodeType.CDATA:
case XmlNodeType.SignificantWhitespace:
{
// Collect text content between start and end of the node
String value = reader.Value;
tempContent.Append(value);
}
break;
}
}
return document;
}