예제 #1
0
        /// <summary>
        /// Creates a clone of the current node
        /// </summary>
        /// <returns>A new OpenNode instance</returns>
        public override Node Clone()
        {
            OpenNode node = new OpenNode(this.Name, "", this.Closed);

            for (int i = 0; i < this.Count; i++)
            {
                string attr = this.GetAttributeName(i);
                node.AddAttribute(attr, this.GetAttribute(attr));
            }
            return(node);
        }
예제 #2
0
        /// <summary>
        /// Parses an AOML string into open, close and content nodes
        /// </summary>
        /// <param name="aoml">The aoml string to be parsed</param>
        public NodeCollection Parse(string aoml)
        {
            NodeCollection nodes = new NodeCollection();

            // Create regular expression instance

            if (this.regex == null)
            {
                this.regex = new Regex(
                    "[<]\\s*(?<closer>[/]?)\\s*" +
                    "(?<name>[a-z]+)" +
                    "(\\s+((?<attribute>[a-z_\\-]+)\\s*" +
                    "(=\\s*(" +
                    /**/ (Mode == ParserMode.Strict ? "" : "(?<value>[^\\s<>'\"]+)|") +
                    /**/ "[\"](?<value>[^\"]*)[\"]|" +
                    /**/ (Mode == ParserMode.Compatibility ? "['](?<value>[^'>]*)[']?)|" : "['](?<value>[^']*)['])|") +
                    /**/ "(?<value>)" +
                    ")?)\\s*)*" +
                    "\\s*(?<closed>[/]?)[>]",
                    RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Multiline);
            }

            // Some setup
            int regexCloser    = this.regex.GroupNumberFromName("closer");
            int regexName      = this.regex.GroupNumberFromName("name");
            int regexAttribute = this.regex.GroupNumberFromName("attribute");
            int regexValue     = this.regex.GroupNumberFromName("value");
            int regexClosed    = this.regex.GroupNumberFromName("closed");

            // Convert to unix line endings
            aoml = aoml.Replace("\r\n", "\n");
            // Parse AOML
            MatchCollection matches = this.regex.Matches(aoml);
            int             offset  = 0;

            foreach (Match match in matches)
            {
                // Extract content
                if (match.Index > offset)
                {
                    string content = aoml.Substring(offset, match.Index - offset);
                    AddContent(nodes, content, content);
                }
                offset = match.Index + match.Length;
                // Extract tag
                string raw  = match.Groups[0].Value;
                string name = match.Groups[regexName].Value;
                if (string.IsNullOrEmpty(name))
                {
                    // No name, let's assume it's just text
                    AddContent(nodes, raw, raw);
                    continue;
                }
                bool closer = !string.IsNullOrEmpty(match.Groups[regexCloser].Value);
                bool closed = !string.IsNullOrEmpty(match.Groups[regexClosed].Value);
                if (closer)
                {
                    // Closing tag
                    nodes.Add(new CloseNode(name, raw));
                }
                else
                {
                    // Opening tag
                    OpenNode node = new OpenNode(name, raw, closed);
                    // Add attributes
                    for (int i = 0; i < match.Groups[regexAttribute].Captures.Count; i++)
                    {
                        node.AddAttribute(
                            match.Groups[regexAttribute].Captures[i].Value,
                            match.Groups[regexValue].Captures[i].Value);
                    }
                    nodes.Add(node);
                }
            }
            // Remainder is content
            if (offset < aoml.Length)
            {
                string content = aoml.Substring(offset);
                AddContent(nodes, content, content);
            }
            return(nodes);
        }