/// <summary> /// Provides the corresponding attributes for the specified element, if they are available /// </summary> private IEnumerable <DtdAttribute> CreateDtdAttributesForElement(DtdElement element) { // Regular expression to find the AttributList-Definition // (?<attributliste><!ATTLIST muster_titel[\t\r\n ]+(?<attribute>[^>]+?)[\t\r\n ]?>) string patternList = "(?<attributliste><!ATTLIST " + element.Name + "[\\t\\r\\n ]+(?<attribute>[^>]+?)[\\t\\r\\n ]?>)"; var regList = new Regex(patternList); //, RegexOptions.IgnoreCase); var match = regList.Match(this.WorkingContent); if (match.Success) { // Get the list of attributes string attributListeCode = match.Groups["attribute"].Value; // Isolate the individual attributes in the list of attributes // Regular expression to find the individual attributes in the AttribuList // [\t\r\n ]?(?<name>[\w-_]+)[\t\r\n ]+(?<typ>CDATA|ID|IDREF|IDREFS|NMTOKEN|NMTOKENS|ENTITY|ENTITIES|NOTATION|xml:|[(][|\w-_ \t\r\n]+[)])[\t\r\n ]+(?:(?<anzahl>#REQUIRED|#IMPLIED|#FIXED)[\t\r\n ]+)?(?:"(?<vorgabewert>[\w-_]+)")?[\t\r\n ]? const string singlePattern = "[\\t\\r\\n ]?(?<name>[\\w-_]+)[\\t\\r\\n ]+(?<typ>CDATA|ID|IDREF|IDREFS|NMTOKEN|NMTOKENS|ENTITY|ENTITIES|NOTATION|xml:|[(][|\\w-_ \\t\\r\\n]+[)])[\\t\\r\\n ]+(?:(?<anzahl>#REQUIRED|#IMPLIED|#FIXED)[\\t\\r\\n ]+)?(?:\"(?<vorgabewert>[\\w-_]+)\")?[\\t\\r\\n ]?"; var singleRegex = new Regex(singlePattern); //, RegexOptions.IgnoreCase); match = singleRegex.Match(attributListeCode); if (match.Success) { DtdAttribute attribut; string type; string[] valuesList; string delimStr = "|"; char[] delimiter = delimStr.ToCharArray(); // Run through all RegEx hits and create attributes for the element while (match.Success) { attribut = new DtdAttribute(); attribut.Name = match.Groups["name"].Value; attribut.StandardValue = match.Groups["vorgabewert"].Value; switch (match.Groups["anzahl"].Value) { case "#REQUIRED": attribut.Mandatory = DtdAttribute.MandatoryTypes.Mandatory; break; case "#IMPLIED": case "": attribut.Mandatory = DtdAttribute.MandatoryTypes.Optional; break; case "#FIXED": attribut.Mandatory = DtdAttribute.MandatoryTypes.Constant; break; default: throw new ApplicationException($"unknown attribute mandatory value '{match.Groups["anzahl"].Value}' in attribute '{match.Value}' of element {element.Name}"); } type = match.Groups["typ"].Value; type = type.Trim(); if (type.StartsWith("(")) // It is an enumeration of the permissible values of this attribute (en1|en2|..) { attribut.Type = ""; // remove brackets type = type.Replace("(", ""); type = type.Replace(")", ""); type = type.Replace(")", ""); // split into values valuesList = type.Split(delimiter, StringSplitOptions.RemoveEmptyEntries); // Split the values separated by | into an array attribut.AllowedValues = valuesList.Select(w => w.Replace("\n", " ").Trim()).ToArray(); } else // it is an exact specification of the type of this attribute like CDATA, ID, IDREF etc. { attribut.Type = type; } yield return(attribut); match = match.NextMatch(); } } else { throw new ApplicationException($"No attributes found in the AttributeList '{attributListeCode}'!"); } } else { Trace.WriteLine($"No attributes available for element {element.Name}."); } }
/// <summary> /// Evaluates the element source code and stores the content structured in the element object /// </summary> /// <example> /// e.g. something like this could be in the element source code: /// <!ELEMENT template (#PCDATA | srai | sr | that | get | bot | birthday | set | A | star | random )*> /// </example> private DtdElement CreateElementFromSourcecode(string elementSourcecode) { if (elementSourcecode == "#PCDATA") // It is not an element defined in the DTD, but the PCDATA element { return(new DtdElement() { Name = "#PCDATA", ChildElements = new DtdChildElements("") }); } if (elementSourcecode == "#COMMENT") // It is not an element defined in the DTD, but the COMMENT element { return(new DtdElement() { Name = "#COMMENT", ChildElements = new DtdChildElements("") }); } // The following expression splits the ELEMENT tag into its parts. groups: // element=the whole element // elementname=the name of the element // innerelements=List of child elements that may occur in the element const string regpatternelement = @"(?<element><!ELEMENT[\t\r\n ]+(?<elementname>[\w-_]+?)([\t\r\n ]+(?<innerelements>[(]([\t\r\n]|.)+?[)][*+]?)?)?(?<empty>[\t\r\n ]+EMPTY)? *>)"; // Assemble regular expression to find the element parts Regex reg = new Regex(regpatternelement); //, RegexOptions.IgnoreCase); Match match = reg.Match(elementSourcecode); if (!match.Success) { throw new ApplicationException($"No occurrence found in element code '{elementSourcecode}'."); } var element = new DtdElement(); // Find out the name of the element if (!match.Groups["elementname"].Success) { throw new ApplicationException($"No name found in element code '{elementSourcecode}'."); } element.Name = match.Groups["elementname"].Value; element.Attributes = CreateDtdAttributesForElement(element).ToArray(); // find child elements if (match.Groups["innerelements"].Success) { ReadChildElements(element, match.Groups["innerelements"].Value); } else { ReadChildElements(element, ""); } match = match.NextMatch(); if (match.Success) { throw new ApplicationException($"More than one occurrence found in element code '{elementSourcecode}'."); } return(element); }
/// <summary> /// Evaluates the element source code and stores the content structured in the object /// </summary> /// <remarks> /// e.g. with the following element source code /// <!ELEMENT template (#PCDATA | srai | sr | that | get | bot | birthday | set | A | star | random )*> /// would be expected as ChildElementSourceCode /// (#PCDATA | srai | sr | that | get | bot | birthday | set | A | star | random )* /// </remarks> private void ReadChildElements(DtdElement element, string childElementsSourcecode) { element.ChildElements = new DtdChildElements(childElementsSourcecode); }
private bool FitsPatternInElement(DtdTestpattern pattern, DtdElement element) { Match match = element.ChildrenRegExObjekt.Match(pattern.CompareStringForRegEx); return(match.Success); }