private RelaxngRef ReadRefPattern() { RelaxngRef r = new RelaxngRef(); FillLocation(r); expect("ref"); r.Name = GetNameAttribute(); if (!IsEmptyElement) { Read(); expectEnd("ref"); } else { Read(); } return(r); }
private RelaxngRef ReadRefPattern () { RelaxngRef r = new RelaxngRef (); FillLocation (r); expect ("ref"); r.Name = GetNameAttribute (); if (!IsEmptyElement) { Read (); expectEnd ("ref"); } else Read (); return r; }
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); }
RelaxngGrammar DtdXsd2Rng (XmlSchema xsd, string ns) { g = new RelaxngGrammar (); g.DefaultNamespace = ns; RelaxngStart start = new RelaxngStart (); g.Starts.Add (start); RelaxngChoice choice = new RelaxngChoice (); start.Pattern = choice; // There are only elements. foreach (XmlSchemaElement el in xsd.Items) { RelaxngDefine def = DefineElement (el); g.Defines.Add (def); RelaxngRef dref = new RelaxngRef (); dref.Name = def.Name; choice.Patterns.Add (dref); } return g; }
RelaxngPattern CreateElement (XmlSchemaElement xse) { if (xse.RefName != XmlQualifiedName.Empty) { RelaxngRef r = new RelaxngRef (); r.Name = xse.RefName.Name; // namespace means nothing here. return r; } RelaxngElement re = new RelaxngElement (); RelaxngName name = new RelaxngName (); name.LocalName = xse.Name; re.NameClass = name; XmlSchemaComplexType ct = xse.SchemaType as XmlSchemaComplexType; foreach (XmlSchemaAttribute a in ct.Attributes) re.Patterns.Add (CreateAttribute (a)); RelaxngPattern rpart; if (ct.Particle == null) rpart = new RelaxngEmpty (); else rpart = CreatePatternFromParticle (ct.Particle); if (ct.IsMixed) { if (rpart.PatternType != RelaxngPatternType.Empty) { RelaxngMixed mixed = new RelaxngMixed (); mixed.Patterns.Add (rpart); rpart = mixed; } else { rpart = new RelaxngText (); } } re.Patterns.Add (rpart); return re; }
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 WriteRef (RelaxngRef r) { if (IsKeyword (r.Name)) w.Write ('\\'); w.Write (r.Name); }
private bool ElementMatches (RelaxngRef el) { RelaxngDefine def = elements [new QName ( source.LocalName, source.NamespaceURI)] as RelaxngDefine; return def != null && def.Name == el.Name; }
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); }
// It returns RelaxngAttribute for local attribute, and // RelaxngRef for global attribute. private RelaxngPattern InferNewAttribute ( QName attrName, bool isNewTypeDefinition) { RelaxngPattern p = null; bool mergedRequired = false; if (attrName.Namespace.Length > 0) { // global attribute; might be already defined. // (Actually RELAX NG has no concept of "global // attributes" but it is still useful to // represent attributes in global scope. RelaxngDefine attr = GetGlobalAttribute ( attrName); if (attr == null) { attr = CreateGlobalAttribute (attrName); attr.Patterns.Add (CreateSimplePattern ( InferSimpleType (source.Value))); } else { RelaxngAttribute a = attr.Patterns [0] as RelaxngAttribute; if (a != null) mergedRequired = true; else { RelaxngOptional opt = (RelaxngOptional) attr.Patterns [0]; a = (RelaxngAttribute) opt.Patterns [0]; } InferMergedAttribute (a); } RelaxngRef r = new RelaxngRef (); r.Name = attr.Name; p = r; } else { // local attribute RelaxngAttribute a = new RelaxngAttribute (); a.NameClass = new RelaxngName ( attrName.Name, attrName.Namespace); a.Pattern = CreateSimplePattern ( InferSimpleType (source.Value)); p = a; } // optional if (laxOccurence || (!isNewTypeDefinition && !mergedRequired)) { RelaxngOptional opt = new RelaxngOptional (); opt.Patterns.Add (p); p = opt; } return p; }
private void InferElement (RelaxngRef r, bool isNew) { RelaxngDefine body = GetDefine (r.Name); InferElement (body, isNew); }
private void Run () { // move to top-level element source.MoveToContent (); int depth = source.Depth; if (source.NodeType != XmlNodeType.Element) throw new ArgumentException ("Argument XmlReader content is expected to be an element."); QName qname = new QName (source.LocalName, source.NamespaceURI); RelaxngDefine el = GetGlobalElement (qname); if (el == null) { el = CreateGlobalElement (qname); InferElement (el, true); } else InferElement (el, false); RelaxngStart start = new RelaxngStart (); start.Combine = "choice"; RelaxngRef topRef = new RelaxngRef (); topRef.Name = el.Name; start.Pattern = topRef; grammar.Starts.Add (start); }