예제 #1
0
        // 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);
        }
예제 #2
0
        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);
        }
예제 #3
0
 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(" }");
 }
예제 #4
0
        // 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)));
        }
예제 #5
0
        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);
                }
            }
        }
예제 #6
0
        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);
        }
예제 #7
0
        // 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);
        }