/// <summary>
        /// Checks all test patterns for validity within the scope of the read DTD
        /// </summary>
        private void CheckAllTestPattern(List <DtdTestpattern> allPattern, XmlCursorPos cursorPos)
        {
            var        node = cursorPos.ActualNode;
            DtdElement element_;

            if (cursorPos.PosOnNode == XmlCursorPositions.CursorInsideTheEmptyNode)
            {
                // Get the DTD element for the node of the cursor
                element_ = dtd.DTDElementByName(Dtd.GetElementNameFromNode(node), false);
            }
            else
            {
                if ((node.OwnerDocument == null) || (node.OwnerDocument.DocumentElement == null))
                {
                    Debug.Assert(false, "Beep!");
                    return;
                }
                else
                {
                    if (node == node.OwnerDocument.DocumentElement) // The node is the root element
                    {
                        // Only the root element is allowed in place of the root element
                        foreach (DtdTestpattern muster in allPattern)
                        {
                            if (muster.ElementName == node.Name) // if it is the root element
                            {
                                muster.Success = true;           // Only the root element is allowed at the position of the root element
                            }
                        }
                        return;
                    }
                    else // The node is not the root element
                    {
                        // Get the DTD element for the parent node of the cursor
                        element_ = dtd.DTDElementByName(Dtd.GetElementNameFromNode(node.ParentNode), false);
                    }
                }
            }

            // Check whether the current DTD run has led to one of the searched test patterns
            foreach (DtdTestpattern muster in allPattern)  // run through all samples to be tested
            {
                if (element_ == null)
                {
                    muster.Success = false; // This element is not known at all
                }
                else
                {
                    if (!muster.Success)
                    {
#if DEBUGTRACE
                        Trace.WriteLine(String.Format("Check für neues Ziel-Muster {0} > {1}", ElementName(muster.Element), muster.Zusammenfassung_));
#endif
                        muster.Success = FitsPatternInElement(muster, element_);
                    }
                }
            }
        }
예제 #2
0
        private bool CheckNodePos(System.Xml.XmlNode node)
        {
            // Comment is always ok
            //if (node is System.Xml.XmlComment) return true;
            // Whitespace is always ok
            if (node is System.Xml.XmlWhitespace)
            {
                return(true);
            }

            if (dtd.IsDtdElementKnown(Dtd.GetElementNameFromNode(node))) // The element of this node is known in the DTD
            {
                try
                {
                    if (this.NodeChecker.IsTheNodeAllowedAtThisPos(node))
                    {
                        return(true);
                    }
                    else
                    {
                        errorMessages.AppendFormat($"Tag '{node.Name}' not allowed here.");
                        var pos = new XmlCursorPos();
                        pos.SetPos(node, XmlCursorPositions.CursorOnNodeStartTag);
                        var allowedTags = this.NodeChecker.AtThisPosAllowedTags(pos, false, false); // what is allowed at this position?
                        if (allowedTags.Length > 0)
                        {
                            errorMessages.Append("At this position allowed:");
                            foreach (string tag in allowedTags)
                            {
                                errorMessages.AppendFormat("{0} ", tag);
                            }
                        }
                        else
                        {
                            errorMessages.Append("No tags are allowed at this point. Probably the parent tag is already invalid.");
                        }
                        return(false);
                    }
                }
                catch (Dtd.XMLUnknownElementException e)
                {
                    errorMessages.AppendFormat($"unknown element '{e.ElementName}'");
                    return(false);
                }
            }
            else // The element of this node is not known in the DTD
            {
                errorMessages.AppendFormat($"unknown element '{Dtd.GetElementNameFromNode(node)}'");
                return(false);
            }
        }
        /// <summary>
        ///  Is the specified element allowed at this point in the XML?
        /// </summary>
        public bool IsTheNodeAllowedAtThisPos(System.Xml.XmlNode node)
        {
            if (node.ParentNode is System.Xml.XmlDocument)
            {   // It is the root element, this cannot be checked against the parent node, but must be compared separately. If it is the root element allowed in the DTD, then ok, otherwise not
                // Implementation: TO DO!
                return(true);
            }
            else
            {
                var cursorPos = new XmlCursorPos();
                cursorPos.SetPos(node, XmlCursorPositions.CursorOnNodeStartTag);

#if ThinkLogging
                _thinkLog = new StringBuilder();
#endif

                // Create the test patterns to insert for all available elements
                var elementName = Dtd.GetElementNameFromNode(node);
                var pattern     = this.CreateTestPattern(elementName, cursorPos);

                // Pack into a test sample list and send the list for testing
                var list = new List <DtdTestpattern>();
                list.Add(pattern);
                this.CheckAllTestPattern(list, cursorPos);

                if (pattern.Success)
                {
#if ThinkLogging
                    _thinkLog = new StringBuilder();
                    _thinkLog.Append(pattern.Summary + "\r\n");
#endif
                    return(true);
                }
                else
                {
                    return(false);
                }
            }
        }
        /// <summary>
        /// Adds a test pattern
        /// </summary>
        private DtdTestpattern CreateTestPattern(string elementName, XmlCursorPos cursorPos)
        {
            DtdTestpattern testPattern;
            var            node = cursorPos.ActualNode;

            System.Xml.XmlNode sibling;

            switch (cursorPos.PosOnNode)
            {
            case XmlCursorPositions.CursorInsideTheEmptyNode:
                // The parent node is empty, so we only have to test for the allowed elements in it and not expect any sibling elements on the same level
                testPattern = new DtdTestpattern(elementName, Dtd.GetElementNameFromNode(node));
                testPattern.AddElement(elementName);
                break;

            default:
                // If the parent node is the XML document itself, then abort here
                if (node.ParentNode is System.Xml.XmlDocument)
                {
                    throw new ApplicationException("No test pattern can be created for the root element. Its validity must be guaranteed by comparison with the DTD root element.");
                }

                testPattern = new DtdTestpattern(elementName, Dtd.GetElementNameFromNode(node.ParentNode));

                // Traverse all elements within the parent element
                sibling = node.ParentNode.FirstChild;
                while (sibling != null)
                {
                    if (sibling is System.Xml.XmlWhitespace)
                    {
                        // Whitespace tags can be ignored during the check
                    }
                    else
                    {
                        if (sibling == node)     // at this point the node must be inserted
                        {
                            if (sibling is System.Xml.XmlComment)
                            {
                                testPattern.AddElement("#COMMENT");
                            }
                            else
                            {
                                if (this.dtd.DTDElementByName(Dtd.GetElementNameFromNode(node), false) == null)
                                {
                                    // This element is not known at all, therefore the element is sometimes not included
                                    // throw new ApplicationException(String.Format("unknown Node-Element '{0}'", DTD.GetElementNameFromNode(node)));
                                }
                                else
                                {
                                    switch (cursorPos.PosOnNode)
                                    {
                                    case XmlCursorPositions.CursorOnNodeStartTag: // If the node itself is selected and should be replaced
                                    case XmlCursorPositions.CursorOnNodeEndTag:
                                        if (elementName == null)                  // check delete
                                        {
                                            // Omit element
                                        }
                                        else         //  check insert/replace
                                        {
                                            // Instead of the element present at this position, the element to be tested is inserted here
                                            testPattern.AddElement(elementName);
                                        }
                                        break;

                                    case XmlCursorPositions.CursorBehindTheNode:
                                        if (elementName == null)          // check delete
                                        {
                                            throw new ApplicationException("CreateTestPattern: Delete must not be checked for XmlCursorPositions.CursorBehindTheNode!");
                                        }
                                        else
                                        {
                                            // element is inserted behind the element to be tested
                                            testPattern.AddElement(Dtd.GetElementNameFromNode(node));
                                            testPattern.AddElement(elementName);
                                        }
                                        break;

                                    case XmlCursorPositions.CursorInsideTheEmptyNode:
                                        if (elementName == null)          // check delete
                                        {
                                            throw new ApplicationException("CreateTestPattern: Delete must not be checked for XmlCursorPositions.CursorInsideTheEmptyNode!");
                                        }
                                        else
                                        {
                                            throw new ApplicationException("CreateTestPattern: CursorInsideTheEmptyNode can´t be handled at this place!");
                                        }


                                    case XmlCursorPositions.CursorInFrontOfNode:
                                        if (elementName == null)          // check delete
                                        {
                                            throw new ApplicationException("CreateTestPattern: Delete must not be checked for XmlCursorPositions.CursorInFrontOfNode!");
                                        }
                                        else
                                        {
                                            // Element is inserted before the element to be tested
                                            testPattern.AddElement(elementName);
                                            testPattern.AddElement(Dtd.GetElementNameFromNode(node));
                                        }
                                        break;

                                    case XmlCursorPositions.CursorInsideTextNode:
                                        if (elementName == null)          // check delete
                                        {
                                            throw new ApplicationException("CreateTestPattern: Delete must not be checked for XmlCursorPositions.CursorInsideTextNode!");
                                        }
                                        else
                                        {
                                            if (Dtd.GetElementNameFromNode(node) != "#PCDATA")
                                            {
                                                throw new ApplicationException("CreateTestPattern: CursorInsideTextNode, but node.name=" + Dtd.GetElementNameFromNode(node));
                                            }
                                            else
                                            {
                                                // The element to be tested is placed between two text nodes
                                                testPattern.AddElement("#PCDATA");
                                                testPattern.AddElement(elementName);
                                                testPattern.AddElement("#PCDATA");
                                            }
                                        }
                                        break;

                                    default:
                                        throw new ApplicationException("Unknown XmlCursorPositions value:" + cursorPos.PosOnNode);
                                    }
                                }
                            }
                        }
                        else     // just continue enumerating the elements as usual
                        {
                            testPattern.AddElement(Dtd.GetElementNameFromNode(sibling));
                        }
                    }
                    sibling = sibling.NextSibling;     // to the next element
                }
                break;
            }
            return(testPattern);
        }