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 (inNode.LeftNode.Accepts(qname))
                        {
                            cnode = inNode.LeftNode;
                            break;
                        }
                        else if (inNode.LeftNode.Nullable())
                        {
                            NodeMatched = 1;
                        }
                        else
                        {
                            goto error;
                        }
                    }

                    if (NodeMatched == 1)
                    {
                        if (inNode.RightNode.Accepts(qname))
                        {
                            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 (inNode.LeftNode.Accepts(qname))
                    {
                        NodeMatched = 0;
                        cnode       = inNode.LeftNode;
                    }
                    else if (inNode.RightNode.Accepts(qname))
                    {
                        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 (inNode.LeftNode.Accepts(qname))
                    {
                        cnode = inNode.LeftNode;
                    }
                    else
                    {
                        goto error;
                    }
                    break;

                case ContentNode.Type.Star:
                case ContentNode.Type.Plus:
                    inNode = (InternalNode)cnode;
                    if (inNode.LeftNode.Accepts(qname))
                    {
                        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 (inNode.LeftNode.Accepts(qname))
                    {
                        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() });
            }
        }
Esempio n. 2
0
        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() });
            }
        }
        internal bool HasMatched(ValidationState context)
        {
            if (IsAllElements)
            {
                if (isAllEmptiable && context.AllElementsSet.IsEmpty)
                {
                    return(true);
                }
                else
                {
                    return(context.AllElementsSet.HasAllBits(this.allElementsSet));
                }
            }

            if (!IsCompiled)
            {
                // MIXED or ELEMENT
                int          NodeMatched = context.HasNodeMatched;
                InternalNode inNode      = (InternalNode)context.CurrentNode;
                if (inNode == contentNode)
                {
                    return(NodeMatched == 1 || inNode.LeftNode.Nullable());
                }
                while (inNode != contentNode)
                {
                    switch (inNode.NodeType)
                    {
                    case ContentNode.Type.Sequence:
                        if (((NodeMatched == 0) && (!inNode.LeftNode.Nullable() || !inNode.RightNode.Nullable())) ||
                            ((NodeMatched == 1) && !inNode.RightNode.Nullable()))
                        {
                            return(false);
                        }
                        break;

                    case ContentNode.Type.Choice:
                        if ((NodeMatched == 0) && !inNode.LeftNode.Nullable() && !inNode.LeftNode.Nullable())
                        {
                            return(false);
                        }
                        break;

                    case ContentNode.Type.Plus:
                        if ((NodeMatched == 0) && !inNode.LeftNode.Nullable())
                        {
                            return(false);
                        }
                        break;

                    case ContentNode.Type.MinMax: {
                        int          min;
                        MinMaxValues mm = (MinMaxValues)context.MinMaxValues[inNode];
                        if (mm == null)
                        {
                            min = ((MinMaxNode)inNode).Min;
                        }
                        else
                        {
                            min = mm.Min;
                        }
                        if ((min > 0) && !inNode.LeftNode.Nullable())
                        {
                            return(false);
                        }
                        break;
                    }

                    case ContentNode.Type.Star:
                    case ContentNode.Type.Qmark:
                    default:
                        break;
                    } // switch

                    NodeMatched = (((InternalNode)inNode.ParentNode).LeftNode == inNode) ? 1 : 2;
                    inNode      = (InternalNode)inNode.ParentNode;
                }

                return(NodeMatched == 1);
            }
            else
            {
                return(context.HasMatched);
            }
        }