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($""); sb.Append($"<{nameof(Conclusions)}>"); if (Conclusions != null) { foreach (var conclusion in Conclusions) { sb.Append(conclusion.ToXml()); } } sb.Append($""); sb.Append($"<{nameof(LabelAssociations)}>"); if (LabelAssociations != null) { foreach (var labelAssociation in LabelAssociations) { sb.Append(labelAssociation.ToXml()); } } sb.Append($""); sb.Append($""); return sb.ToString(); } } }