コード例 #1
0
ファイル: RelaxngInference.cs プロジェクト: pmq20/mono_forked
        private void InferContent(RelaxngElement ct, bool isNew)
        {
            source.Read();
            source.MoveToContent();
            switch (source.NodeType)
            {
            case XmlNodeType.EndElement:
                InferAsEmptyElement(ct, isNew);
                break;

            case XmlNodeType.Element:
                InferComplexContent(ct, isNew);
                break;

            case XmlNodeType.Text:
            case XmlNodeType.CDATA:
            case XmlNodeType.SignificantWhitespace:
                InferTextContent(ct, isNew);
                source.MoveToContent();
                if (source.NodeType == XmlNodeType.Element)
                {
                    goto case XmlNodeType.Element;
                }
                break;

            case XmlNodeType.Whitespace:
                InferContent(ct, isNew);                  // skip and retry
                break;
            }
        }
コード例 #2
0
ファイル: RelaxngInference.cs プロジェクト: pmq20/mono_forked
        private void InferComplexContent(RelaxngElement ct, bool isNew)
        {
            bool           makeMixed = false;
            RelaxngPattern content   = GetElementContent(ct);

            if (content != null)
            {
                switch (content.PatternType)
                {
                case RelaxngPatternType.Text:
                case RelaxngPatternType.Data:
                    makeMixed = true;
                    ct.Patterns.Remove(content);
                    ct.Patterns.Add(new RelaxngGroup());
                    break;
                }
            }
            else
            {
                ct.Patterns.Add(new RelaxngGroup());
            }
            InferComplexContentCore(ct, isNew);
            if (makeMixed)
            {
                MarkAsMixed(ct);
            }
        }
コード例 #3
0
ファイル: RelaxngInference.cs プロジェクト: pmq20/mono_forked
        private void InferElement(RelaxngDefine el, bool isNew)
        {
            RelaxngElement ct = (RelaxngElement)el.Patterns [0];

            // Attributes
            if (source.MoveToFirstAttribute())
            {
                InferAttributes(ct, isNew);
                source.MoveToElement();
            }

            // Content
            if (source.IsEmptyElement)
            {
                InferAsEmptyElement(ct, isNew);
                source.Read();
                source.MoveToContent();
            }
            else
            {
                InferContent(ct, isNew);
                source.ReadEndElement();
            }
            if (GetElementContent(ct) == null)
            {
                el.Patterns.Add(new RelaxngEmpty());
            }
        }
コード例 #4
0
ファイル: RncWriter.cs プロジェクト: pmq20/mono_forked
 public void WriteElement(RelaxngElement element)
 {
     w.Write("element ");
     element.NameClass.WriteRnc(this);
     w.Write(" {");
     WritePatterns(element.Patterns, false);
     w.Write("}");
 }
コード例 #5
0
ファイル: dtd2rng.cs プロジェクト: pmq20/mono_forked
        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);
        }
コード例 #6
0
ファイル: RelaxngInference.cs プロジェクト: pmq20/mono_forked
        private void InferTextContent(RelaxngElement ct, bool isNew)
        {
            string         value = source.ReadString();
            RelaxngPattern p     = GetElementContent(ct);

            if (p == null)
            {
                ct.Patterns.Add(CreateSimplePattern(
                                    InferSimpleType(value)));
                return;
            }
            RelaxngPatternList pl = null;

            switch (p.PatternType)
            {
            case RelaxngPatternType.Text:
            case RelaxngPatternType.Data:
                return;                 // no way to narrow it to data.

            case RelaxngPatternType.Empty:
                ct.Patterns.Remove(p);
                ct.Patterns.Add(new RelaxngText());
                return;

            case RelaxngPatternType.Group:
                pl = ((RelaxngBinaryContentPattern)p).Patterns;
                break;

            case RelaxngPatternType.Optional:
            case RelaxngPatternType.ZeroOrMore:
            case RelaxngPatternType.OneOrMore:
                pl = ((RelaxngSingleContentPattern)p).Patterns;
                break;

            default:
                throw Error(p, "Unexpected pattern");
            }
            if (pl.Count > 0 && pl [0] is RelaxngMixed)
            {
                return;
            }
            RelaxngMixed m = new RelaxngMixed();

            while (pl.Count > 0)
            {
                RelaxngPattern child = pl [0];
                m.Patterns.Add(child);
                pl.Remove(child);
            }
            pl.Add(m);
        }
コード例 #7
0
ファイル: RelaxngInference.cs プロジェクト: pmq20/mono_forked
        // Already relaxed.
        private RelaxngDefine CreateGlobalElement(QName name)
        {
            RelaxngDefine def = new RelaxngDefine();

            def.Name = CreateUniqueName(name.Name);
            RelaxngElement el = new RelaxngElement();

            el.NameClass = new RelaxngName(name.Name,
                                           name.Namespace);
            def.Patterns.Add(el);
            elements.Add(name, def);
            grammar.Defines.Add(def);
            return(def);
        }
コード例 #8
0
ファイル: RelaxngInference.cs プロジェクト: pmq20/mono_forked
        // Change pattern as to allow text content.
        private void MarkAsMixed(RelaxngElement ct)
        {
            RelaxngPattern p = GetElementContent(ct);

            // empty
            if (p == null || p is RelaxngEmpty)
            {
                if (p != null)
                {
                    ct.Patterns.Remove(p);
                }
                ct.Patterns.Add(new RelaxngText());
                return;
            }
            // text
            switch (p.PatternType)
            {
            case RelaxngPatternType.Text:
            case RelaxngPatternType.Data:
            case RelaxngPatternType.Mixed:
                return;

            case RelaxngPatternType.Choice:
            case RelaxngPatternType.Group:
                RelaxngBinaryContentPattern b =
                    (RelaxngBinaryContentPattern)p;
                if (b != null)
                {
                    RelaxngMixed m = b.Patterns [0]
                                     as RelaxngMixed;
                    if (m == null)
                    {
                        m = new RelaxngMixed();
                        while (b.Patterns.Count > 0)
                        {
                            RelaxngPattern child =
                                b.Patterns [0];
                            m.Patterns.Add(child);
                            b.Patterns.Remove(child);
                        }
                        b.Patterns.Add(m);
                    }
                }
                break;

            default:
                throw Error(p, "Not allowed pattern.");
            }
        }
コード例 #9
0
ファイル: RelaxngInference.cs プロジェクト: pmq20/mono_forked
        private RelaxngPattern GetElementContent(RelaxngElement el)
        {
            if (el.Patterns.Count == 0)
            {
                return(null);
            }
            RelaxngPattern p = el.Patterns [0];

            if (p is RelaxngInterleave)
            {
                return(el.Patterns.Count == 2 ?
                       el.Patterns [1] : null);
            }
            else
            {
                return(p);
            }
        }
コード例 #10
0
ファイル: RelaxngInference.cs プロジェクト: pmq20/mono_forked
        // 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);
        }
コード例 #11
0
ファイル: RelaxngInference.cs プロジェクト: pmq20/mono_forked
        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);
                }
            }
        }
コード例 #12
0
ファイル: RelaxngInference.cs プロジェクト: pmq20/mono_forked
        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);
        }
コード例 #13
0
ファイル: RelaxngInference.cs プロジェクト: pmq20/mono_forked
        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));
                }
            }
        }
コード例 #14
0
ファイル: RelaxngInference.cs プロジェクト: pmq20/mono_forked
        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);
        }
コード例 #15
0
ファイル: RelaxngInference.cs プロジェクト: pmq20/mono_forked
 private RelaxngInterleave GetAttributes(RelaxngElement el)
 {
     return(el.Patterns.Count > 0 ?
            el.Patterns [0] as RelaxngInterleave : null);
 }
コード例 #16
0
ファイル: RelaxngInference.cs プロジェクト: pmq20/mono_forked
        private void InferAttributes(RelaxngElement ct, bool isNew)
        {
            RelaxngInterleave attList = null;
            Hashtable         table   = null;

            do
            {
                if (source.NamespaceURI == NamespaceXmlns)
                {
                    continue;
                }

                if (table == null)
                {
                    attList = GetAttributes(ct);
                    table   = CollectAttrTable(attList);
                }
                QName attrName = new QName(
                    source.LocalName, source.NamespaceURI);
                RelaxngPattern attr = table [attrName]
                                      as RelaxngPattern;
                if (attr == null)
                {
                    if (attList == null)
                    {
                        attList = new RelaxngInterleave();
                        ct.Patterns.Insert(0, attList);
                    }
                    attList.Patterns.Add(
                        InferNewAttribute(
                            attrName, isNew));
                }
                else
                {
                    table.Remove(attrName);
                    if (attrName.Namespace.Length > 0)
                    {
                        RelaxngDefine ga = GetGlobalAttribute(attrName);
                        InferMergedAttribute(
                            ga.Patterns [0]);
                    }
                    else
                    {
                        InferMergedAttribute(attr);
                    }
                }
            } while (source.MoveToNextAttribute());

            // mark all attr definitions that did not appear
            // as optional.
            if (table != null)
            {
                foreach (RelaxngPattern attr in table.Values)
                {
                    if (attr is RelaxngOptional)
                    {
                        continue;
                    }
                    attList.Patterns.Remove(attr);
                    RelaxngOptional opt = new RelaxngOptional();
                    opt.Patterns.Add(attr);
                    attList.Patterns.Add(opt);
                }
            }
        }