// 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 RelaxngDefine CreateGlobalAttribute(QName name) { RelaxngDefine def = new RelaxngDefine(); def.Name = CreateUniqueName(name.Name + "-attr"); RelaxngAttribute attr = new RelaxngAttribute(); attr.NameClass = new RelaxngName( name.Name, name.Namespace); def.Patterns.Add(attr); attributes.Add(name, def); grammar.Defines.Add(def); return(def); }
public void WriteAttribute(RelaxngAttribute attribute) { w.Write("attribute "); attribute.NameClass.WriteRnc(this); w.Write(" {"); if (attribute.Pattern == null) { w.Write("empty"); } else { attribute.Pattern.WriteRnc(this); } w.Write(" }"); }
// validate string value agains attr and // if invalid, then relax the type. private void InferMergedAttribute(RelaxngPattern ap) { switch (ap.PatternType) { case RelaxngPatternType.Ref: string refName = ((RelaxngRef)ap).Name; RelaxngDefine def = GetDefine(refName); InferMergedAttribute(def.Patterns [0]); return; case RelaxngPatternType.Optional: InferMergedAttribute( ((RelaxngOptional)ap).Patterns [0]); return; } RelaxngAttribute attr = (RelaxngAttribute)ap; RelaxngPattern p = attr.Pattern; if (p is RelaxngText) { return; // We could do nothing anymore. } if (p is RelaxngEmpty) { if (source.Value.Length == 0) { return; // We can keep empty. } // We still could infer a choice of empty and // data, but it's being too complicated. So // here we just set text. attr.Pattern = new RelaxngText(); return; } RelaxngData data = p as RelaxngData; if (data == null) { throw Error(p, "This inference implementation only allows text, empty and data for an attribute."); } attr.Pattern = CreateSimplePattern( InferMergedType(source.Value, new QName(data.Type, data.DatatypeLibrary))); }
private RngInference(XmlReader xmlReader, RelaxngGrammar grammar, bool laxOccurence, bool laxTypeInference) { this.source = xmlReader; this.grammar = grammar; this.laxOccurence = laxOccurence; this.laxTypeInference = laxTypeInference; nsmgr = new XmlNamespaceManager(source.NameTable); foreach (RelaxngDefine def in grammar.Defines) { if (def.Patterns.Count != 1) { continue; } RelaxngElement e = def.Patterns [0] as RelaxngElement; RelaxngAttribute a = def.Patterns [0] as RelaxngAttribute; if (e == null && a == null) { continue; } RelaxngName rn = e != null ? e.NameClass as RelaxngName : a.NameClass as RelaxngName; if (rn == null) { continue; } QName qname = new QName(rn.LocalName, rn.Namespace); if (e != null) { elements.Add(qname, def); } else { attributes.Add(qname, def); } } }
RelaxngPattern CreateAttribute(XmlSchemaAttribute attr) { RelaxngAttribute ra = new RelaxngAttribute(); RelaxngName name = new RelaxngName(); name.LocalName = attr.Name; ra.NameClass = name; ra.Pattern = attr.SchemaType != null? CreatePatternFromType(attr.SchemaType) : CreatePatternFromTypeName(attr.SchemaTypeName); RelaxngPattern ret = ra; if (attr.Use == XmlSchemaUse.Optional) { RelaxngOptional opt = new RelaxngOptional(); opt.Patterns.Add(ra); ret = opt; } return(ret); }
// get attribute definition table. private Hashtable CollectAttrTable(RelaxngInterleave attList) { Hashtable table = new Hashtable(); if (attList == null) { return(table); } foreach (RelaxngPattern p in attList.Patterns) { RelaxngAttribute a = p as RelaxngAttribute; if (a == null) { a = (RelaxngAttribute) ((RelaxngOptional)p) .Patterns [0]; } RelaxngName rn = a.NameClass as RelaxngName; table.Add(new QName( rn.LocalName, rn.Namespace), a); } return(table); }