RelaxngPattern CreatePatternFromParticleCore(XmlSchemaParticle xsdp) { XmlSchemaGroupBase gb = xsdp as XmlSchemaGroupBase; if (xsdp is XmlSchemaAny) { RelaxngRef r = new RelaxngRef(); r.Name = "anyType"; return(r); } if (gb is XmlSchemaSequence) { RelaxngGroup grp = new RelaxngGroup(); foreach (XmlSchemaParticle xsdc in gb.Items) { grp.Patterns.Add(CreatePatternFromParticle(xsdc)); } return(grp); } if (gb is XmlSchemaChoice) { RelaxngChoice rc = new RelaxngChoice(); foreach (XmlSchemaParticle xsdc in gb.Items) { rc.Patterns.Add(CreatePatternFromParticle(xsdc)); } return(rc); } return(CreateElement((XmlSchemaElement)xsdp)); }
// Note that it does not return the changed sequence. private RelaxngSingleContentPattern ToSequenceOfChoice( RelaxngElement ct, RelaxngGroup s) { RelaxngSingleContentPattern scp = laxOccurence ? (RelaxngSingleContentPattern) new RelaxngZeroOrMore() : new RelaxngOneOrMore(); RelaxngChoice c = new RelaxngChoice(); foreach (RelaxngPattern p in s.Patterns) { c.Patterns.Add(p); } scp.Patterns.Add(c); ct.Patterns.Clear(); ct.Patterns.Add(scp); return(scp); }
private void InferAsEmptyElement(RelaxngElement ct, bool isNew) { RelaxngPattern content = GetElementContent(ct); if (content == null) { ct.Patterns.Add(new RelaxngEmpty()); return; } RelaxngGroup g = content as RelaxngGroup; if (g == null) { return; } RelaxngOptional opt = new RelaxngOptional(); opt.Patterns.Add(g); ct.Patterns.Remove(content); ct.Patterns.Add(opt); }
private void ProcessSequence(RelaxngElement ct, RelaxngGroup s, ref int position, ref bool consumed, bool isNew) { RelaxngMixed m = s.Patterns.Count > 0 ? s.Patterns [0] as RelaxngMixed : null; RelaxngPatternList pl = m != null ? m.Patterns : s.Patterns; for (int i = 0; i < position; i++) { RelaxngPattern p = pl [i]; RelaxngRef iel = p as RelaxngRef; if (iel == null) { RelaxngOneOrMore oom = p as RelaxngOneOrMore; iel = (RelaxngRef)oom.Patterns [0]; } if (ElementMatches(iel)) { // Sequence element type violation // might happen (might not, but we // cannot backtrack here). So switch // to sequence of choice* here. ProcessLax(ToSequenceOfChoice(ct, s)); return; } } if (pl.Count <= position) { QName name = new QName(source.LocalName, source.NamespaceURI); RelaxngDefine nel = GetGlobalElement(name); if (nel != null) { InferElement(nel, false); } else { nel = CreateGlobalElement(name); // used to be CreateElement(). InferElement(nel, true); } RelaxngRef re = new RelaxngRef(); re.Name = nel.Name; pl.Add(re); consumed = true; return; } RelaxngPattern c = pl [position]; RelaxngRef el = c as RelaxngRef; if (el == null) { RelaxngOneOrMore oom = c as RelaxngOneOrMore; el = (RelaxngRef)oom.Patterns [0]; } if (el == null) { throw Error(s, String.Format("Target complex type content sequence has an unacceptable type of particle {0}", s.Patterns [position])); } bool matches = ElementMatches(el); if (matches) { if (consumed && c is RelaxngRef) { RelaxngOneOrMore oom = new RelaxngOneOrMore(); oom.Patterns.Add(el); pl [position] = oom; } InferElement(el, false); source.MoveToContent(); switch (source.NodeType) { case XmlNodeType.None: if (source.NodeType == XmlNodeType.Element) { goto case XmlNodeType.Element; } else if (source.NodeType == XmlNodeType.EndElement) { goto case XmlNodeType.EndElement; } break; case XmlNodeType.Element: ProcessSequence(ct, s, ref position, ref consumed, isNew); break; case XmlNodeType.Text: case XmlNodeType.CDATA: case XmlNodeType.SignificantWhitespace: MarkAsMixed(ct); source.ReadString(); goto case XmlNodeType.None; case XmlNodeType.Whitespace: source.ReadString(); goto case XmlNodeType.None; case XmlNodeType.EndElement: return; default: source.Read(); break; } } else { if (consumed) { position++; consumed = false; ProcessSequence(ct, s, ref position, ref consumed, isNew); } else { ProcessLax(ToSequenceOfChoice(ct, s)); } } }
private void InferComplexContentCore(RelaxngElement ct, bool isNew) { int position = 0; bool consumed = false; do { switch (source.NodeType) { case XmlNodeType.Element: RelaxngPattern p = GetElementContent(ct); RelaxngGroup g = null; if (p == null) { g = new RelaxngGroup(); } switch (p.PatternType) { case RelaxngPatternType.OneOrMore: case RelaxngPatternType.ZeroOrMore: ProcessLax((RelaxngSingleContentPattern)p); break; case RelaxngPatternType.Optional: g = (RelaxngGroup) ((RelaxngOptional)p) .Patterns [0]; goto default; case RelaxngPatternType.Group: g = (RelaxngGroup)p; goto default; case RelaxngPatternType.Text: case RelaxngPatternType.Data: g = new RelaxngGroup(); g.Patterns.Add(new RelaxngMixed()); goto default; default: if (g == null) { throw Error(p, "Unexpected pattern: " + p.PatternType); } ProcessSequence(ct, g, ref position, ref consumed, isNew); break; } source.MoveToContent(); break; case XmlNodeType.Text: case XmlNodeType.CDATA: case XmlNodeType.SignificantWhitespace: MarkAsMixed(ct); source.ReadString(); source.MoveToContent(); break; case XmlNodeType.EndElement: return; // finished case XmlNodeType.None: throw new NotImplementedException("Internal Error: Should not happen."); } } while (true); }
public void WriteGroup(RelaxngGroup p) { WritePatterns(p.Patterns, ',', false); }