private void parseAttributeSelecotr() { attributeSelector attributeselector = new attributeSelector(); attributeselector.wholeText = _selectorText; attributeselector.matchType = enumAttributeType.defaultHas; // default is exactly equal without any *~|.. if (_buffer.Length > 0) { attributeselector.elementE = AppendCleanBuffer(_buffer); } char current = ReadNext(); while (!stop) { if (current == '=') { if (_buffer.Length > 0) { attributeselector.attributeName = AppendCleanBuffer(_buffer); } if (attributeselector.matchType == enumAttributeType.defaultHas) { attributeselector.matchType = enumAttributeType.exactlyEqual; } current = ReadNext(); } else if (current == '~') { if (_buffer.Length > 0) { attributeselector.attributeName = AppendCleanBuffer(_buffer); } attributeselector.matchType = enumAttributeType.whitespaceSeperated; current = ReadNext(); } else if (current == '^') { if (_buffer.Length > 0) { attributeselector.attributeName = AppendCleanBuffer(_buffer); } attributeselector.matchType = enumAttributeType.exactlyBegin; current = ReadNext(); } else if (current == '$') { if (_buffer.Length > 0) { attributeselector.attributeName = AppendCleanBuffer(_buffer); } attributeselector.matchType = enumAttributeType.exactlyEnd; current = ReadNext(); } else if (current == '*') { if (_buffer.Length > 0) { attributeselector.attributeName = AppendCleanBuffer(_buffer); } attributeselector.matchType = enumAttributeType.contains; current = ReadNext(); } else if (current == '|') { if (_buffer.Length > 0) { attributeselector.attributeName = AppendCleanBuffer(_buffer); } attributeselector.matchType = enumAttributeType.hyphenSeperated; current = ReadNext(); } //"'" (U+0027) //U+0022 QUOTATION MARK (") else if (current == '\u0027' || current == '\u0022') { //ignore the ' " mark. current = ReadNext(); } else if (current == ']') { break; } else { _buffer.Append(current); current = ReadNext(); } } if (_buffer.Length > 0) { string value = AppendCleanBuffer(_buffer); if (!string.IsNullOrEmpty(value)) { if (string.IsNullOrEmpty(attributeselector.attributeName)) { attributeselector.attributeName = value; } else { attributeselector.attributeValue = value; } } } simple = attributeselector; }
private static bool matchAttribute(Element element, attributeSelector attSelector) { if (!string.IsNullOrEmpty(attSelector.elementE) && attSelector.elementE != "*") { if (element.tagName != attSelector.elementE.ToLower()) { return(false); } } ///E[foo] an E element with a "foo" attribute //E[foo="bar"] an E element whose "foo" attribute value is exactly equal to "bar" Attribute selectors 2 //E[foo~="bar"] an E element whose "foo" attribute value is a list of whitespace-separated values, one of which is exactly equal to "bar" Attribute selectors 2 //E[foo^="bar"] an E element whose "foo" attribute value begins exactly with the string "bar" Attribute selectors 3 //E[foo$="bar"] an E element whose "foo" attribute value ends exactly with the string "bar" Attribute selectors 3 //E[foo*="bar"] an E element whose "foo" attribute value contains the substring "bar" Attribute selectors 3 //E[foo|="en"] an E element whose "foo" attribute has a hyphen-separated list of values beginning (from the left) with "en" Attribute selectors 2 //[att|=val] //Represents an element with the att attribute, its value either being exactly "val" or beginning with "val" immediately followed by "-" (U+002D). This is primarily intended to allow language subcode matches (e.g., the hreflang attribute on the a element in HTML) as described in BCP 47 ([BCP47]) or its successor. For lang (or xml:lang) language subcode matching, please see the :lang pseudo-class. switch (attSelector.matchType) { case enumAttributeType.exactlyEqual: { string attvalue = element.getAttribute(attSelector.attributeName); return(attvalue == attSelector.attributeValue); } case enumAttributeType.whitespaceSeperated: { string attvalue = element.getAttribute(attSelector.attributeName); if (string.IsNullOrEmpty(attvalue)) { return(false); } string[] liststr = attvalue.Split(' '); foreach (var item in liststr) { if (item == attSelector.attributeValue) { return(true); } } return(false); } case enumAttributeType.exactlyBegin: { string attvalue = element.getAttribute(attSelector.attributeName); if (string.IsNullOrEmpty(attvalue)) { return(false); } if (attvalue.StartsWith(attSelector.attributeValue)) { return(true); } else { return(false); } } case enumAttributeType.exactlyEnd: { string attvalue = element.getAttribute(attSelector.attributeName); if (string.IsNullOrEmpty(attvalue)) { return(false); } if (attvalue.EndsWith(attSelector.attributeValue)) { return(true); } else { return(false); } } case enumAttributeType.contains: { string attvalue = element.getAttribute(attSelector.attributeName); if (string.IsNullOrEmpty(attvalue)) { return(false); } if (attvalue.Contains(attSelector.attributeValue)) { return(true); } else { return(false); } } case enumAttributeType.hyphenSeperated: { /// The following selector represents an a element for which the /// value of the hreflang attribute begins with "en", /// including "en", "en-US", and "en-scouse": string attvalue = element.getAttribute(attSelector.attributeName); if (string.IsNullOrEmpty(attvalue)) { return(false); } if (attvalue == attSelector.attributeValue) { return(true); } if (attvalue.StartsWith(attSelector.attributeValue + '\u002D'.ToString())) { return(true); } return(false); } case enumAttributeType.defaultHas: { return(element.hasAttribute(attSelector.attributeName)); } default: { return(element.hasAttribute(attSelector.attributeName)); } } }