Exemple #1
0
        protected ContentNode right;   // right node
                                       // if node type is QMark, Closure, or Type.Plus, right node is NULL

        internal InternalNode(ContentNode l, ContentNode r, ContentNode.Type t)
        {
            left        = l;
            right       = r;
            contentType = t;
        }
        internal void    Finish(ValidationEventHandler eventHandler, bool compile)
        {
            stack      = null;
            IsCompiled = !abnormalContent && compile;
            if (contentNode == null)
            {
                return;
            }

#if DEBUG
            StringBuilder bb = new StringBuilder();
            contentNode.Dump(bb);
            Debug.WriteLineIf(CompModSwitches.XmlSchema.TraceVerbose, "\t\t\tContent: (" + bb.ToString() + ")");
#endif

            // add end node
            endNode     = NewTerminalNode(XmlQualifiedName.Empty);
            contentNode = new InternalNode(contentNode, endNode, ContentNode.Type.Sequence);
            ((InternalNode)contentNode).LeftNode.ParentNode = contentNode;
            endNode.ParentNode = contentNode;

            if (!IsCompiled)
            {
                CheckXsdDeterministic(eventHandler);
                return;
            }

            if (nodeTable == null)
            {
                nodeTable = new Hashtable();
            }

            // calculate followpos
            int      terminals = terminalNodes.Count;
            BitSet[] followpos = new BitSet[terminals];
            for (int i = 0; i < terminals; i++)
            {
                followpos[i] = new BitSet(terminals);
            }
            contentNode.CalcFollowpos(followpos);

            // state table
            ArrayList Dstates = new ArrayList(16);
            // transition table
            dtrans = new ArrayList(16);
            // lists unmarked states
            ArrayList unmarked = new ArrayList(16);
            // state lookup table
            Hashtable statetable = new Hashtable();

            BitSet empty = new BitSet(terminals);
            statetable.Add(empty, -1);

            // start with firstpos at the root
            BitSet set = contentNode.Firstpos(terminals);
            statetable.Add(set, Dstates.Count);
            unmarked.Add(set);
            Dstates.Add(set);

            int[] a = new int[symbols.Count + 1];
            dtrans.Add(a);
            if (set.Get(endNode.Pos))
            {
                a[symbols.Count] = 1;   // accepting
            }

            // current state processed
            int state = 0;

            // check all unmarked states
            while (unmarked.Count > 0)
            {
                int[] t = (int[])dtrans[state];

                set = (BitSet)unmarked[0];
                CheckDeterministic(set, terminals, eventHandler);
                unmarked.RemoveAt(0);

                // check all input symbols
                for (int sym = 0; sym < symbols.Count; sym++)
                {
                    XmlQualifiedName n      = (XmlQualifiedName)symbols[sym];
                    BitSet           newset = new BitSet(terminals);

                    // if symbol is in the set add followpos to new set
                    for (int i = 0; i < terminals; i++)
                    {
                        if (set.Get(i) && n.Equals(((TerminalNode)terminalNodes[i]).Name))
                        {
                            newset.Or(followpos[i]);
                        }
                    }

                    Object lookup = statetable[newset];
                    // this state will transition to
                    int transitionTo;
                    // if new set is not in states add it
                    if (lookup == null)
                    {
                        transitionTo = Dstates.Count;
                        statetable.Add(newset, transitionTo);
                        unmarked.Add(newset);
                        Dstates.Add(newset);
                        a = new int[symbols.Count + 1];
                        dtrans.Add(a);
                        if (newset.Get(endNode.Pos))
                        {
                            a[symbols.Count] = 1;   // accepting
                        }
                    }
                    else
                    {
                        transitionTo = (int)lookup;
                    }
                    // set the transition for the symbol
                    t[sym] = transitionTo;
                }
                state++;
            }

            nodeTable = null;
        }
        private void CheckXsdContent(ValidationState context, XmlQualifiedName qname, ref XmlSchemaContentProcessing processContents)
        {
            ContentNode  cnode     = context.CurrentNode;
            Object       lookup    = symbolTable[qname];
            int          terminals = symbols.Count;
            MinMaxNode   ln;
            InternalNode inNode;
            MinMaxValues mm;
            int          NodeMatched = context.HasNodeMatched;

            while (true)
            {
                switch (cnode.NodeType)
                {
                case ContentNode.Type.Any:
                case ContentNode.Type.Terminal:
                    context.HasNodeMatched = (((InternalNode)cnode.ParentNode).LeftNode == cnode) ? 1 : 2;
                    context.CurrentNode    = cnode.ParentNode;
                    context.HasMatched     = (cnode.ParentNode == endNode);
                    if (cnode.NodeType == ContentNode.Type.Any)
                    {
                        processContents = ((AnyNode)cnode).ProcessContents;
                    }
                    return;

                case ContentNode.Type.Sequence:
                    inNode = (InternalNode)cnode;
                    if (NodeMatched == 0)
                    {
                        if (Accepts(inNode.LeftNode, qname, terminals, lookup))
                        {
                            cnode = inNode.LeftNode;
                            break;
                        }
                        else if (inNode.LeftNode.Nullable())
                        {
                            NodeMatched = 1;
                        }
                        else
                        {
                            goto error;
                        }
                    }

                    if (NodeMatched == 1)
                    {
                        if (Accepts(inNode.RightNode, qname, terminals, lookup))
                        {
                            NodeMatched = 0;
                            cnode       = inNode.RightNode;
                            break;
                        }
                        else if (inNode.RightNode.Nullable())
                        {
                            NodeMatched = 2;
                        }
                        else
                        {
                            goto error;
                        }
                    }

                    if (NodeMatched == 2)
                    {
                        if (cnode.ParentNode != null)
                        {
                            if (((InternalNode)cnode.ParentNode).LeftNode == cnode)
                            {
                                NodeMatched = 1;
                            }
                            cnode = cnode.ParentNode;
                            break;
                        }
                        else
                        {
                            goto error;
                        }
                    }
                    break;

                case ContentNode.Type.Choice:
                    inNode = (InternalNode)cnode;
                    if (NodeMatched != 0)
                    {
                        NodeMatched = (((InternalNode)cnode.ParentNode).LeftNode == cnode) ? 1 : 2;
                        cnode       = cnode.ParentNode;
                    }
                    else if (Accepts(inNode.LeftNode, qname, terminals, lookup))
                    {
                        NodeMatched = 0;
                        cnode       = inNode.LeftNode;
                    }
                    else if (Accepts(inNode.RightNode, qname, terminals, lookup))
                    {
                        NodeMatched = 0;
                        cnode       = inNode.RightNode;
                    }
                    else
                    {
                        goto error;
                    }
                    break;

                case ContentNode.Type.Qmark:
                    inNode = (InternalNode)cnode;
                    if (NodeMatched != 0)
                    {
                        NodeMatched = (((InternalNode)cnode.ParentNode).LeftNode == cnode) ? 1 : 2;
                        cnode       = cnode.ParentNode;
                    }
                    else if (Accepts(inNode.LeftNode, qname, terminals, lookup))
                    {
                        cnode = inNode.LeftNode;
                    }
                    else
                    {
                        goto error;
                    }
                    break;

                case ContentNode.Type.Star:
                case ContentNode.Type.Plus:
                    inNode = (InternalNode)cnode;
                    if (Accepts(inNode.LeftNode, qname, terminals, lookup))
                    {
                        NodeMatched = 0;
                        cnode       = inNode.LeftNode;
                    }
                    else
                    {
                        NodeMatched = (((InternalNode)cnode.ParentNode).LeftNode == cnode) ? 1 : 2;
                        cnode       = cnode.ParentNode;
                    }
                    break;

                case ContentNode.Type.MinMax:
                    inNode = (InternalNode)cnode;
                    ln     = (MinMaxNode)cnode;
                    mm     = null;
                    if (context.MinMaxValues != null)
                    {
                        mm = (MinMaxValues)context.MinMaxValues[ln];
                    }
                    else
                    {
                        context.MinMaxValues = new Hashtable();
                    }
                    if (mm == null)
                    {
                        // new minmaxnode and add it to minmaxnodes hashtable
                        mm = new MinMaxValues(ln.Min, ln.Max);
                        context.MinMaxValues.Add(ln, mm);
                    }

                    if (mm.Max == 0)
                    {
                        NodeMatched = (((InternalNode)cnode.ParentNode).LeftNode == cnode) ? 1 : 2;
                        cnode       = cnode.ParentNode;
                        mm.Max      = ln.Max;
                        mm.Min      = ln.Min;
                    }
                    else if (Accepts(inNode.LeftNode, qname, terminals, lookup))
                    {
                        mm.Max     -= 1;
                        mm.Min     -= 1;
                        NodeMatched = 0;
                        cnode       = inNode.LeftNode;
                    }
                    else
                    {
                        if (mm.Min > 0)
                        {
                            goto error;
                        }
                        NodeMatched = (((InternalNode)cnode.ParentNode).LeftNode == cnode) ? 1 : 2;
                        cnode       = cnode.ParentNode;
                        mm.Max      = ln.Max;
                        mm.Min      = ln.Min;
                    }
                    break;
                } // switch
            }     // while (true)

error:
            context.NeedValidateChildren = false;
            ArrayList v = ExpectedXsdElements(context.CurrentNode, NodeMatched);

            if (v == null)
            {
                throw new XmlSchemaException(Res.Sch_InvalidContent, context.Name.ToString());
            }
            else
            {
                throw new XmlSchemaException(Res.Sch_InvalidContentExpecting, new string[] { context.Name.ToString(), v.ToString() });
            }
        }
 //  returns names of all legal elements following the specified state
 private ArrayList ExpectedXsdElements(ContentNode cnode, int NodeMatched)
 {
     return(null);
 }