I have an XML file describing a website. It consists of the Site as the root node that can have Pages, Pages can have Objects such as Button or TextBox and Dialogs. Dialogs can also have Objects.
In the corresponding C# classes, all is derived from Element. When I deserialize the XML, how can I have a reference to the Parent of the element getting constructed?
I was told complex types can't de deserialized that way but if I add an ID field to each element in the XML then the parent can be referenced using that and hence be deserialized properly. How would I implement that? I wouldn't want to manually add an ID field to each element in the XML file...
My element class:
public class Element
{
public string Name { get; set; }
public string TagName { get; set; }
public string XPath { get; set; }
[XmlElement(ElementName = "Site", Type = typeof(Site))]
[XmlElement(ElementName = "Page", Type = typeof(Page))]
[XmlElement(ElementName = "Dialog", Type = typeof(Dialog))]
public Element Parent { get; set; }
[XmlArray("Children", IsNullable = false)]
[XmlArrayItem(Type = typeof(TextBox))]
[XmlArrayItem(Type = typeof(Page))]
[XmlArrayItem(Type = typeof(Button))]
[XmlArrayItem(Type = typeof(Dialog))]
public Collection<Element> Children { get; set; }
}
My deserialization:
public Site GetSiteFromXml(string filePath, string fileName)
{
XmlSerializer serializer = new XmlSerializer(typeof(Site));
return serializer.Deserialize(new XmlTextReader(Path.Combine(filePath, fileName))) as Site;
}
My XML file:
<Site>
<Name>WebSiteName</Name>
<Url>https://site.url</Url>
<Children>
<Page>
<Name>HomePage</Name>
<Address>#page=1</Address>
<Children>
<Button>
<Name>LoginDialogButton</Name>
<Id>LoginIcon</Id>
<XPath>//*[@id="LoginIcon"]</XPath>
<Enabled>true</Enabled>
<Action>OpenLoginDialog</Action>
</Button>
<Dialog>
<Name>LoginPopUpDialog</Name>
<Id>loginModal</Id>
<Children>
<TextBox>
<Name>UserNameInput</Name>
</TextBox>
<TextBox>
<Name>PasswordInput</Name>
</TextBox>
<Button>
<Name>LoginButton</Name>
<Action>DialogDismiss</Action>
</Button>
</Children>
</Dialog>
</Children>
</Page>
</Children>
</Site>