RelaxngPattern CreatePatternFromParticle(XmlSchemaParticle xsdp) { RelaxngSingleContentPattern rngp = null; if (xsdp.MinOccurs == 0 && xsdp.MaxOccursString == "unbounded") { rngp = new RelaxngZeroOrMore(); } else if (xsdp.MinOccurs == 1 && xsdp.MaxOccursString == "unbounded") { rngp = new RelaxngOneOrMore(); } else if (xsdp.MinOccurs == 0) { rngp = new RelaxngOptional(); } RelaxngPattern child = CreatePatternFromParticleCore(xsdp); if (rngp == null) { return(child); } rngp.Patterns.Add(child); return(rngp); }
private void ProcessLax(RelaxngSingleContentPattern scp) { RelaxngChoice c = (RelaxngChoice)scp.Patterns [0]; foreach (RelaxngPattern p in c.Patterns) { RelaxngRef el = p as RelaxngRef; if (el == null) { RelaxngOneOrMore oom = (RelaxngOneOrMore)p; el = (RelaxngRef)oom.Patterns [0]; } if (el == null) { throw Error(c, String.Format("Target pattern contains unacceptable child pattern {0}. Only ref is allowed here.")); } if (ElementMatches(el)) { InferElement(el, false); return; } } // append a new element particle to lax term. QName qname = new QName( source.LocalName, source.NamespaceURI); RelaxngDefine def = GetGlobalElement(qname); if (def == null) { def = CreateGlobalElement(qname); // used to be CreateElement(). InferElement(def, true); } else { InferElement(def, false); } RelaxngRef nel = new RelaxngRef(); nel.Name = def.Name; c.Patterns.Add(nel); }
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)); } } }
public void WriteOneOrMore(RelaxngOneOrMore p) { WritePatterns(p.Patterns, true); w.Write('+'); }