Пример #1
0
        internal ElementTypeRef IsValidSequence(ElementType et, ICollection s, int index)
        {
            ICollection col=et.ContentModel.GetValidFirstElements();

            int count=0;
            ElementTypeRef ret=null;
            foreach ( XmlName name in s )
            {
                count++;

                if ( !et.HasChildElement(name) )
                    // ignore elements that simply aren't in the model
                    // TODO: H: count can get out
                    continue;

                ElementTypeRef sr=FindInCollection(col, name);
                if ( count == index+1 )
                {
                    ret=sr;
                }

                if ( sr == null )
                {
                    // element name is not allowed here
                    if ( ret != null && count < index+1 )
                        return ret;

                    return null;
                }

                // TODO: M: optimise - this is called at end of s even though not going to loop again
                col=sr.OriginalReference.GetValidNextElements();
            }
            // TODO: M: think about required elements at end - but probably
            //			not needed here because don't want to stop someone
            //			adding an element even if more are allowed
            return ret;
        }
Пример #2
0
        public void Validate(XmlElement e, ElementType et, ICollection list)
        {
            switch ( et.ContentType )
            {
                case ElementContentType.Any:
                    ValidateAnyModel();
                    break;

                case ElementContentType.Element:
                    ValidateElementModel(e, et, list);
                    break;

                case ElementContentType.Empty:
                    ValidateEmptyModel(list);
                    break;

                case ElementContentType.Mixed:
                    ValidateMixedModel(et, list);
                    break;

                case ElementContentType.PCDATA:
                    ValidateTextModel(list);
                    break;
            }
        }
Пример #3
0
        internal bool IsValid(ElementType et, ICollection list)
        {
            switch ( et.ContentType )
            {
                case ElementContentType.Any:
                    return true;

                case ElementContentType.Element:
                    return IsValidElementContent(et, list);

                case ElementContentType.Empty:
                    // TODO: H: too simplistic
                    return list.Count == 0;

                case ElementContentType.Mixed:
                    return IsValidMixedContent(et, list);

                case ElementContentType.PCDATA:
                    return IsValidTextContent(et, list);

                default:
                    // can never happen due to enum
                    throw new InvalidOperationException("Unrecognised ElementContentType enum");
            }
        }
Пример #4
0
 public void AddChildElement(ElementType child)
 {
     if ( children[child.Name] == null )
         children.Add(child.Name, child);
 }
Пример #5
0
        void getMixedContent(ElementType parent)
        {
            bool moreNames = true;

            discardWhitespace();
            requireString("PCDATA");
            discardWhitespace();
            if (isChar('|'))
            {
                // Content model is mixed: (#PCDATA | A | B)*

                parent.ContentType = ElementContentType.Mixed;

                // Add a choice Group for the content model.

                parent.ContentModel = new ContentModel();
                parent.ContentModel.Type = ParticleType.Choice;
                parent.ContentModel.IsRequired = false;
                parent.ContentModel.IsRepeatable = true;

                // Process the element type names. There must be at least one,
                // or we would have fallen into the else clause below.

                while (moreNames)
                {
                    discardWhitespace();
                    getReference(parent.ContentModel, parent, true);
                    discardWhitespace();
                    moreNames = isChar('|');
                }

                // Close the content model.

                requireString(")*");
            }
            else
            {
                // Content model is PCDATA-only: (#PCDATA)

                parent.ContentType = ElementContentType.PCDATA;
                requireChar(')');

                // 5/17/00, Ronald Bourret
                // Check if there is an asterisk after the closing parenthesis.
                // This covers the following case:
                //    <!ELEMENT A (#PCDATA)*>

                isChar('*');
            }
        }
Пример #6
0
        private bool IsValidMixedContent(ElementType et, ICollection list)
        {
            // list is assumed to contain all children (including indirect children via entity reference)
            foreach ( XmlNode n in list )
            {
                XmlElement e=n as XmlElement;
                if ( e == null )
                    continue;

                bool valid=false;
                foreach ( ElementType ct in et.ChildElements )
                {
                    if ( ct.Name.QualifiedName.Equals(n.Name) )
                    {
                        valid=true;
                        break;
                    }
                }
                if ( !valid )
                    return false;
            }
            return true;
        }
Пример #7
0
        private void ValidateElementModel(XmlElement e, ElementType et, ICollection children)
        {
            ICollection col=et.ContentModel.GetValidFirstElements();

            bool elementMissing=false;
            foreach ( XmlNode n in children )
            {
                client.StartChildValidation(n);

                if ( n.NodeType == XmlNodeType.Text )
                {
                    client.ProcessError(n, ValidationErrorType.NodeNotAllowed);
                }
                else if ( n.NodeType == XmlNodeType.Element )
                {
                    ElementType et2=documentType.GetElementType((XmlElement) n);
                    if ( et2 == null )
                        // not in DTD, will be picked up later
                        continue;

                    // TODO: E: entities!
                    if ( !et.HasChildElement(new XmlName(n)) )
                    {
                        // this element can never be allowed here
                        client.ProcessError(n, ValidationErrorType.ElementNotInContentModel);
                        continue;
                    }

                    if ( elementMissing )
                        continue;

                    ElementTypeRef sr=FindInCollection(col, (XmlElement) n);
                    if ( sr == null )
                    {
                        foreach ( ElementTypeRef etr in col )
                        {
                            if ( etr.IsRequired )
                            {
                                elementMissing=true;
                                client.ProcessError(n, ValidationErrorType.ElementNotAllowedHere);
                                break;
                            }
                        }
                        if ( elementMissing )
                            continue;

                        client.ProcessError(n, ValidationErrorType.NodeNotAllowed);
                    }
                    else
                        col=sr.OriginalReference.GetValidNextElements();
                }
            }
            if ( !elementMissing )
            {
                foreach ( ElementTypeRef sr in col )
                {
                    if ( sr.IsRequired )
                    {
                        // TODO: M: can provide some more info to the error here
                        client.ProcessError(e, ValidationErrorType.RequiredElementMissing);
                        break;
                    }
                }
            }
        }
Пример #8
0
        Attribute getAttribute(ElementType elementType)
        {
            XmlName name;
            Attribute attribute;

            // Get the attribute name and create a new Attribute.

            name = getXMLName();
            attribute = new Attribute(name);

            // If the element does not have an attribute with this name, add
            // it to the ElementType. Otherwise, ignore it.

            elementType.AddAttribute(attribute);

            // Return the new Attribute. Note that we do this even if it is
            // not added to the ElementType so that other code is simpler.

            return attribute;
        }
Пример #9
0
        void getContentModel(ElementType elementType)
        {
            // Get the content model.

            if (isChar('('))
            {
                // 5/18/00, Ronald Bourret
                // Added following call to discardWhitespace(). This is needed
                // for the case where space precedes the '#':
                //    <!ELEMENT A ( #PCDATA | B )*>

                discardWhitespace();
                if (isChar('#'))
                {
                    getMixedContent(elementType);
                }
                else
                {
                    getElementContent(elementType);
                }
            }
            else if (isString("EMPTY"))
            {
                elementType.ContentType = ElementContentType.Empty;
            }
            else if (isString("ANY"))
            {
                elementType.ContentType = ElementContentType.Any;
            }
            else
                throwXMLMiddlewareException("Invalid element type declaration.");
        }
Пример #10
0
        Reference getReference(Group group, ElementType parent, bool mixed)
        {
            //      XMLName     name;
            ElementType child;
            Reference   rf;

            // Create an ElementType for the referenced child.

            child = createElementType();

            // Add the child to the parent and vice versa. If we are processing
            // mixed content, then each child must be unique in the parent.

            if ( mixed )
            {
                if (parent.HasChildElement(child.Name))
                    throwXMLMiddlewareException("The element type " + child.Name + " appeared more than once in the declaration of mixed content for the element type " + parent.Name + ".");
            }

            parent.AddChildElement(child);
            child.AddParentElement(parent);

            // Create a Reference for the child, add it to the group, and return it.

            rf = new Reference(child);
            group.AddMember(rf);
            return rf;
        }
Пример #11
0
        void getAttDef(ElementType elementType)
        {
            // S already parsed.

            Attribute attribute;

            attribute = getAttribute(elementType);
            requireWhitespace();
            getAttributeType(attribute);
            requireWhitespace();
            getAttributeRequired(attribute);
        }
Пример #12
0
        internal Style GetStyle(IGraphics gr, Style parentStyle, XmlElement e, ElementType et)
        {
            Style ret=parentStyle == null ? blockStyle : parentStyle;

            bool foundMatch=false;
            foreach ( Style s in Styles )
            {
                if ( s.IsMatch(e.CreateNavigator(), nsMgr) )
                {
                    ret=Cascade(gr, ret, s);
                    foundMatch=true;
                }
            }

            bool emptyModel=et != null && et.ContentType == ElementContentType.Empty;

            if ( !foundMatch )
            {
                // TODO: M: could optimise this perhaps
                XmlElement parent=e.ParentNode as XmlElement;
                if ( parent == null )
                    ret=Cascade(gr, ret, new BlockStyle());
                else if ( HasText(parent) || emptyModel )
                    ret=Cascade(gr, ret, new InlineStyle());
                else
                    ret=Cascade(gr, ret, new BlockStyle());
            }

            if ( e.HasChildNodes )
                // if element has child nodes, it cannot be shown as empty
                ret.Empty=false;
            else if ( emptyModel )
                // empty element in DTD so flag as such
                ret.Empty=true;

            return ret;
        }
Пример #13
0
 internal Style GetStyle(IGraphics gr, XmlElement e, ElementType et)
 {
     return GetStyle(gr, null, e, et);
 }
Пример #14
0
 public void AddParentElement(ElementType parent)
 {
     if ( parents[parent.Name] == null )
         parents.Add(parent.Name, parent);
 }
Пример #15
0
        private ElementListItem[] FindValidElements(ElementType et, XmlElement parent, XmlNode n, bool replace)
        {
            int index=-1;

            ArrayList children=new ArrayList();
            foreach ( XmlNode c in parent.ChildNodes )
            {
                if ( c.Equals(n) )
                    index=children.Count;

                if ( c.NodeType != XmlNodeType.Element )
                    continue;

                XmlName xn=new XmlName(c);
                children.Add(xn);
            }
            if ( index < 0 )
            {
                Debug.Assert(!replace, "This can't happen if in replace mode");
                children.Add(null);
                index=children.Count-1;
            }
            else
            {
                if ( !replace )
                    children.Insert(index, null);
            }

            ArrayList ret=new ArrayList();
            foreach ( ElementType t in et.ChildElements )
            {
                children[index]=t.Name;

                ElementTypeRef sr=IsValidSequence(et, children, index);
                if ( sr != null )
                    ret.Add(new ElementListItem(sr.Name, sr.IsRequired, sr.IsChoice));
            }
            return ret.ToArray(typeof(ElementListItem)) as ElementListItem[];
        }
Пример #16
0
        void getContentParticle(Group group, ElementType parent)
        {
            Group     childGroup;
            Reference rf;

            if (isChar('('))
            {
                childGroup = new Group();
                group.AddMember(childGroup);
                getGroup(childGroup, parent);
            }
            else
            {
                rf = getReference(group, parent, false);
                getFrequency(rf);
            }
        }
Пример #17
0
        private bool IsValidElementContent(ElementType et, ICollection list)
        {
            // list is assumed to contain all children (including indirect children via entity reference)
            ICollection col=et.ContentModel.GetValidFirstElements();

            foreach ( XmlNode n in list )
            {
                if ( XmlUtil.IsTextContent(n) )
                    return false;

                XmlElement e=n as XmlElement;
                if ( e == null )
                    // not significant, eg. comment
                    continue;

                ElementTypeRef sr=FindInCollection(col, new XmlName(e));
                if ( sr == null )
                    return false;

                col=sr.OriginalReference.GetValidNextElements();
            }
            // TODO: think about required elements (remaining col)
            return true;
        }
Пример #18
0
 void getElementContent(ElementType elementType)
 {
     elementType.ContentModel = new ContentModel();
     elementType.ContentType = ElementContentType.Element;
     getGroup(elementType.ContentModel, elementType);
     elementType.ContentModel.FinaliseGroup();
 }
Пример #19
0
 private bool IsValidTextContent(ElementType et, ICollection list)
 {
     foreach ( XmlNode n in list )
     {
         XmlElement e=n as XmlElement;
         // TODO: E: entities
         if ( e != null )
             return false;
     }
     return true;
 }
Пример #20
0
        void getGroup(Group group, ElementType parent)
        {
            // This gets a choice or sequence.

            bool moreCPs = true;

            while (moreCPs)
            {
                discardWhitespace();
                getContentParticle(group, parent);
                discardWhitespace();
                if (isChar('|'))
                {
                    if (group.Type == ParticleType.Unknown)
                    {
                        group.Type = ParticleType.Choice;
                    }
                    else if (group.Type == ParticleType.Sequence)
                    {
                        throwXMLMiddlewareException("Invalid mixture of ',' and '|' in content model.");
                    }
                }
                else if (isChar(','))
                {
                    if (group.Type == ParticleType.Unknown)
                    {
                        group.Type = ParticleType.Sequence;
                    }
                    else if (group.Type == ParticleType.Choice)
                    {
                        throwXMLMiddlewareException("Invalid mixture of ',' and '|' in content model.");
                    }
                }
                else if (isChar(')'))
                {
                    moreCPs = false;
                    getFrequency(group);

                    // If there is a single content particle in the group,
                    // we simply call it a sequence.

                    if (group.Type == ParticleType.Unknown)
                    {
                        group.Type = ParticleType.Sequence;
                    }
                }
            }
            group.FinaliseGroup();
        }
Пример #21
0
        private void ValidateMixedModel(ElementType et, ICollection list)
        {
            foreach ( XmlNode n in list )
            {
                client.StartChildValidation(n);

                if ( n.NodeType != XmlNodeType.Element )
                    // TODO: H: entities!
                    continue;
            //				{
            //					RemoveValidationErrors(n);
            //					continue;
            //				}

                if ( !et.HasChildElement(new XmlName(n.Name)) )
                    client.ProcessError(n, ValidationErrorType.ElementNotInContentModel);
            }
        }
Пример #22
0
        /**
         * Create an ElementType by XMLName.
         *
         * <p>If the ElementType already exists, it is returned. Otherwise, a new
         * ElementType is created.</p>
         *
         * @param name The XMLName of the element type.
         * @return The ElementType.
         */
        public ElementType CreateElementType(XmlName name)
        {
            // Get an existing ElementType or add a new one if it doesn't exist.
            //
            // This method exists because we frequently need to refer to an
            // ElementType object before it is formally created. For example, if
            // element type A is defined before element type B, and the content model
            // of element type A contains element type B, we need to add the
            // ElementType object for B (as a reference in the content model of A)
            // before it is formally defined and created.

            ElementType elementType;

            elementType = (ElementType)elementTypes[name];
            if (elementType == null)
            {
                elementType = new ElementType(name);
                elementTypes[name]=elementType;
            }

            return elementType;
        }