internal static ElementExp[] Collect(Expression exp, XmlName tagName) { ContentModelCollector col = new ContentModelCollector(tagName); exp.Visit(col); return(col.matched); }
private Expression OnElement(Expression contentModel, Expression[] atoms) { contentModel = VerifyText(contentModel, atoms); Trace.WriteLine("<" + document.Name + ">"); Trace.Indent(); Trace.WriteLine("expecting: " + ExpPrinter.printContentModel(contentModel)); ElementExp[] match = ContentModelCollector.Collect( contentModel, new XmlName(document.NamespaceURI, document.LocalName)); if (match[0] == null) { // error: unexpected element ReportError(ERR_UNEXPECTED_ELEMENT, document.Name); } Expression combinedChild = Expression.NotAllowed; int i; for (i = 0; match[i] != null; i++) { combinedChild = builder.CreateChoice(combinedChild, match[i].exp); } int clen = i; Expression[] cp = null; if (clen > 1) { Trace.WriteLine(string.Format("{0} elements are matched", clen)); cp = new Expression[clen]; for (i = 0; i < clen; i++) { cp[i] = match[i].exp; } } Trace.WriteLine("combined child: " + ExpPrinter.printContentModel(combinedChild)); if (document.MoveToFirstAttribute()) { do { combinedChild = OnAttribute(combinedChild, cp); } while(document.MoveToNextAttribute()); } document.MoveToElement(); combinedChild = attPruner.prune(combinedChild); if (combinedChild == Expression.NotAllowed) { // error: required attribute is missing // TODO: name of required attributes ReportError(ERR_MISSING_ATTRIBUTE); } if (!document.IsEmptyElement) { document.ReadStartElement(); combinedChild = Verify(combinedChild, cp); combinedChild = VerifyText(combinedChild, cp); Trace.Unindent(); Trace.WriteLine("</" + document.Name + ">"); } else { // treat it as "" combinedChild = VerifyText(combinedChild, cp); Trace.Unindent(); Trace.WriteLine("</" + document.Name + ">"); } if (!combinedChild.IsNullable) { // error: unexpected end of element. ReportError(ERR_CONTENTMODEL_INCOMPLETE, document.Name); } document.Read(); // read the end tag. if (cp != null) { for (i = 0; i < clen; i++) { if (!cp[i].IsNullable) { match[i] = null; } } } ElementToken e = new ElementToken(match, clen); if (atoms != null) { for (i = 0; i < atoms.Length; i++) { atoms[i] = Residual.Calc(atoms[i], e, builder); } } contentModel = Residual.Calc(contentModel, e, builder); Trace.WriteLine("residual: " + ExpPrinter.printContentModel(contentModel)); return(contentModel); }