using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml;
namespace AIPractice.Shared.Labels
{
public class RootLabel:LabelObject
{
private enum ReadingNode
{
///
/// 无意义节点
///
None,
///
/// 正在读取描述
///
Descriptions,
///
/// 正在读取结论
///
Conclusions,
///
/// 正在读取关联关系
///
LabelAssociations
}
///
/// Gets all Descriptions belongs to this root label.
///
public IReadOnlyList Descriptions { get; }
///
/// Gets all conclusions belongs to this root label.
///
public IReadOnlyList Conclusions { get; }
///
/// Gets or label associations of this root label.
///
public IReadOnlyList LabelAssociations { get; }
///
/// Gets or sets if this root label needs the parts conclusion.
///
public bool NeedPartsConclusion { get; set; }
public RootLabel(string id, string title, IEnumerable descriptions,
IEnumerable conclusions, IEnumerable labelAssociations) : base(id, title)
{
Descriptions = new List(descriptions);
Conclusions = new List(conclusions);
LabelAssociations = new List(labelAssociations);
foreach(var group in Descriptions)
{
group.Root = this;
}
foreach (var group in Conclusions)
{
group.Root = this;
}
}
///
/// Add one group into the descriptions.
///
/// The group to be added
public void AddDescriptionGroup(LabelGroup group)
{
var groupList = (List)Descriptions;
if (!groupList.Contains(group))
{
groupList.Add(group);
group.Root = this;
}
}
///
/// Remove the group from the descriptions.
///
/// The group to be removed.
public void RemoveDescriptionGroup(LabelGroup group)
{
var groupList = (List)Descriptions;
if (groupList.Contains(group))
{
groupList.Remove(group);
}
}
///
/// Insert one group into the descriptions on given index.
///
/// The index to be insert.
/// The group to be added. and the root label will be assigned to the group.
public void InsertDescriptionGroup(int index, LabelGroup group)
{
var groupList = (List)Descriptions;
if (!groupList.Contains(group))
{
groupList.Insert(index,group);
group.Root = this;
}
}
///
/// Add one group into the Conclusions.
///
/// The group to be added
public void AddConclusionGroup(LabelGroup group)
{
var groupList = (List)Conclusions;
if (!groupList.Contains(group))
{
groupList.Add(group);
group.Root = this;
}
}
///
/// Remove the group from the Conclusions.
///
/// The group to be removed.
public void RemoveConclusionGroup(LabelGroup group)
{
var groupList = (List)Conclusions;
if (groupList.Contains(group))
{
groupList.Remove(group);
}
}
///
/// Insert one group into the Conclusions on given index.
///
/// The index to be insert.
/// The group to be added. and the root label will be assigned to the group.
public void InsertConclusionGroup(int index, LabelGroup group)
{
var groupList = (List)Conclusions;
if (!groupList.Contains(group))
{
groupList.Insert(index, group);
group.Root = this;
}
}
///
/// Add one association into the root.
///
/// The association to be added
public void AddLabelAssociation(LabelAssociation association)
{
var associationList = (List)LabelAssociations;
var exists = associationList.FirstOrDefault(x => x.Left.Id == association.Left.Id && x.Right.Id == association.Right.Id);
if (exists == null)
{
associationList.Add(association);
}
}
///
/// Remove the association from the root.
///
/// The association to be removed.
public void RemoveLabelAssociation(LabelAssociation association)
{
var associationList = (List)LabelAssociations;
var exists = associationList.FirstOrDefault(x => x.Left.Id == association.Left.Id && x.Right.Id == association.Right.Id);
if (exists != null)
{
associationList.Remove(exists);
}
}
///
/// Clear all associations.
///
public void ClearLabelAssociations()
{
var associationList = (List)LabelAssociations;
associationList.Clear();
}
public static RootLabel FromXml(string xmlContent)
{
using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(xmlContent)))
{
using (XmlReader r = XmlReader.Create(ms))
{
r.Read();
var readingNode = ReadingNode.None;
var id = r.GetAttribute("id");
var title = r.GetAttribute("title");
var needPartsConclusionStr = r.GetAttribute("needPartsConclusion");
bool.TryParse(needPartsConclusionStr, out bool needPartsConclusion);
var descriptions = new List();
var conclusions = new List();
var labelAssociations = new List();
while (r.NodeType == XmlNodeType.Element &&
(r.Name == nameof(SingleSelectionLabelGroup) ||
r.Name == nameof(MultiSelectionLabelGroup) ||
r.Name == nameof(LabelAssociation)) || r.Read())
{
if (r.NodeType == XmlNodeType.EndElement && r.Name == nameof(RootLabel))
{
break;
}
if (r.NodeType == XmlNodeType.Element && r.Name == nameof(Descriptions))
{
readingNode = ReadingNode.Descriptions;
}
if (r.NodeType == XmlNodeType.Element && r.Name == nameof(Conclusions))
{
readingNode = ReadingNode.Conclusions;
}
if (r.NodeType == XmlNodeType.Element && r.Name == nameof(LabelAssociations))
{
readingNode = ReadingNode.LabelAssociations;
}
if (r.NodeType == XmlNodeType.Element && r.Name == nameof(SingleSelectionLabelGroup))
{
if (readingNode == ReadingNode.Descriptions)
{
descriptions.Add(SingleSelectionLabelGroup.FromXml(r.ReadOuterXml()));
}
else if(readingNode == ReadingNode.Conclusions)
{
conclusions.Add(SingleSelectionLabelGroup.FromXml(r.ReadOuterXml()));
}
}
if (r.NodeType == XmlNodeType.Element && r.Name == nameof(MultiSelectionLabelGroup))
{
if (readingNode == ReadingNode.Descriptions)
{
descriptions.Add(MultiSelectionLabelGroup.FromXml(r.ReadOuterXml()));
}
else if (readingNode == ReadingNode.Conclusions)
{
conclusions.Add(MultiSelectionLabelGroup.FromXml(r.ReadOuterXml()));
}
}
if (r.NodeType == XmlNodeType.Element && r.Name == nameof(LabelAssociation))
{
if (readingNode == ReadingNode.LabelAssociations)
{
labelAssociations.Add(LabelAssociation.FromXml(r.ReadOuterXml()));
}
}
}
return new RootLabel(id, title, descriptions,conclusions, labelAssociations)
{
NeedPartsConclusion = needPartsConclusion,
};
}
}
}
public override string ToXml()
{
var sb = new StringBuilder();
sb.Append($"<{nameof(RootLabel)} id=\"{Id}\" title=\"{Title}\" needPartsConclusion=\"{NeedPartsConclusion}\">");
sb.Append($"<{nameof(Descriptions)}>");
if (Descriptions != null)
{
foreach (var description in Descriptions)
{
sb.Append(description.ToXml());
}
}
sb.Append($"{nameof(Descriptions)}>");
sb.Append($"<{nameof(Conclusions)}>");
if (Conclusions != null)
{
foreach (var conclusion in Conclusions)
{
sb.Append(conclusion.ToXml());
}
}
sb.Append($"{nameof(Conclusions)}>");
sb.Append($"<{nameof(LabelAssociations)}>");
if (LabelAssociations != null)
{
foreach (var labelAssociation in LabelAssociations)
{
sb.Append(labelAssociation.ToXml());
}
}
sb.Append($"{nameof(LabelAssociations)}>");
sb.Append($"{nameof(RootLabel)}>");
return sb.ToString();
}
}
}