/// <summary> /// More http://www.w3.org/TR/REC-xml/#NT-Name. /// </summary> /// <param name="c">The next input character.</param> /// <param name="tag">The current tag token.</param> /// <returns>The emitted token.</returns> XmlToken TagName(Char c, XmlTagToken tag) { if (Specification.IsSpaceCharacter(c)) { tag.Name = stringBuffer.ToString(); return AttributeBeforeName(src.Next, tag); } else if (c == Specification.SOLIDUS) { tag.Name = stringBuffer.ToString(); return TagSelfClosing(src.Next, tag); } else if (c == Specification.GT) { tag.Name = stringBuffer.ToString(); return EmitTag(tag); } else if (c == Specification.NULL) { RaiseErrorOccurred(ErrorCode.NULL); stringBuffer.Append(Specification.REPLACEMENT); return TagName(src.Next, tag); } else if (c == Specification.EOF) { RaiseErrorOccurred(ErrorCode.EOF); return XmlToken.EOF; } else { stringBuffer.Append(c); return TagName(src.Next, tag); } }
/// <summary> /// More http://www.w3.org/TR/REC-xml/#d0e2480. /// </summary> /// <param name="c">The next input character.</param> /// <param name="tag">The current tag token.</param> XmlToken TagSelfClosing(Char c, XmlTagToken tag) { if (c == Specification.GT) { tag.IsSelfClosing = true; return EmitTag(tag); } else if (c == Specification.EOF) { RaiseErrorOccurred(ErrorCode.EOF); return XmlToken.EOF; } else { RaiseErrorOccurred(ErrorCode.ClosingSlashMisplaced); return AttributeBeforeName(c, tag); } }
/// <summary> /// More http://www.w3.org/TR/REC-xml/#NT-Attribute. /// </summary> /// <param name="c">The next input character.</param> /// <param name="tag">The current tag token.</param> XmlToken AttributeAfterValue(Char c, XmlTagToken tag) { if (Specification.IsSpaceCharacter(c)) return AttributeBeforeName(src.Next, tag); else if (c == Specification.SOLIDUS) return TagSelfClosing(src.Next, tag); else if (c == Specification.GT) return EmitTag(tag); else if (c == Specification.EOF) return XmlTagToken.EOF; RaiseErrorOccurred(ErrorCode.AttributeNameExpected); return AttributeBeforeName(c, tag); }
/// <summary> /// Emits the current token as a tag token. /// </summary> XmlTagToken EmitTag(XmlTagToken tag) { if (tag.Type == XmlTokenType.StartTag) { for (var i = tag.Attributes.Count - 1; i > 0; i--) { for (var j = i - 1; j >= 0; j--) { if (tag.Attributes[j].Key == tag.Attributes[i].Key) { tag.Attributes.RemoveAt(i); RaiseErrorOccurred(ErrorCode.AttributeDuplicateOmitted); break; } } } } else { if (tag.IsSelfClosing) RaiseErrorOccurred(ErrorCode.EndTagCannotBeSelfClosed); if (tag.Attributes.Count > 0) RaiseErrorOccurred(ErrorCode.EndTagCannotHaveAttributes); } return tag; }
/// <summary> /// More http://www.w3.org/TR/REC-xml/#NT-Attribute. /// </summary> /// <param name="c">The next input character.</param> /// <param name="tag">The current tag token.</param> XmlToken AttributeBeforeValue(Char c, XmlTagToken tag) { while (Specification.IsSpaceCharacter(c)) c = src.Next; if (c == Specification.DQ) { stringBuffer.Clear(); return AttributeDoubleQuotedValue(src.Next, tag); } else if (c == Specification.SQ) { stringBuffer.Clear(); return AttributeSingleQuotedValue(src.Next, tag); } else if (c == Specification.GT) { RaiseErrorOccurred(ErrorCode.TagClosedWrong); return EmitTag(tag); } else if (c == Specification.EOF) { return XmlToken.EOF; } throw new ArgumentException("Argument values have to be double or single quoted."); }
/// <summary> /// More http://www.w3.org/TR/REC-xml/#NT-Attribute. /// </summary> /// <param name="c">The next input character.</param> /// <param name="tag">The current tag token.</param> XmlToken AttributeSingleQuotedValue(Char c, XmlTagToken tag) { while (true) { if (c == Specification.SQ) { tag.SetAttributeValue(stringBuffer.ToString()); return AttributeAfterValue(src.Next, tag); } else if (c == Specification.AMPERSAND) { var value = CharacterReference(src.Next); if (value == null) stringBuffer.Append(Specification.AMPERSAND); else stringBuffer.Append(value); } else if (c == Specification.NULL) { RaiseErrorOccurred(ErrorCode.NULL); stringBuffer.Append(Specification.REPLACEMENT); } else if (c == Specification.EOF) return XmlToken.EOF; else stringBuffer.Append(c); c = src.Next; } }
/// <summary> /// More http://www.w3.org/TR/REC-xml/#NT-Attribute. /// </summary> /// <param name="c">The next input character.</param> /// <param name="tag">The current tag token.</param> XmlToken AttributeName(Char c, XmlTagToken tag) { while (true) { if (c.IsSpaceCharacter()) { tag.AddAttribute(_stringBuffer.ToString()); return AttributeAfterName(_src.Next, tag); } else if (c == Specification.SOLIDUS) { tag.AddAttribute(_stringBuffer.ToString()); return TagSelfClosing(_src.Next, tag); } else if (c == Specification.EQ) { tag.AddAttribute(_stringBuffer.ToString()); return AttributeBeforeValue(_src.Next, tag); } else if (c == Specification.GT) { tag.AddAttribute(_stringBuffer.ToString()); return EmitTag(tag); } else if (c == Specification.NULL) { RaiseErrorOccurred(ErrorCode.NULL); _stringBuffer.Append(Specification.REPLACEMENT); } else if (c == Specification.DQ || c == Specification.SQ || c == Specification.LT) { RaiseErrorOccurred(ErrorCode.AttributeNameInvalid); _stringBuffer.Append(c); } else if (c == Specification.EOF) { return XmlToken.EOF; } else _stringBuffer.Append(c); c = _src.Next; } }
/// <summary> /// More http://www.w3.org/TR/REC-xml/#NT-Attribute. /// </summary> /// <param name="c">The next input character.</param> /// <param name="tag">The current tag token.</param> XmlToken AttributeAfterName(Char c, XmlTagToken tag) { while (Specification.IsSpaceCharacter(c)) c = src.Next; if (c == Specification.SOLIDUS) { return TagSelfClosing(src.Next, tag); } else if (c == Specification.EQ) { return AttributeBeforeValue(src.Next, tag); } else if (c == Specification.GT) { return EmitTag(tag); } else if (c == Specification.NULL) { RaiseErrorOccurred(ErrorCode.NULL); stringBuffer.Clear(); stringBuffer.Append(Specification.REPLACEMENT); return AttributeName(src.Next, tag); } else if (c == Specification.DQ || c == Specification.SQ || c == Specification.LT) { RaiseErrorOccurred(ErrorCode.AttributeNameInvalid); stringBuffer.Clear(); stringBuffer.Append(c); return AttributeName(src.Next, tag); } else if (c == Specification.EOF) { return XmlToken.EOF; } else { stringBuffer.Clear(); stringBuffer.Append(c); return AttributeName(src.Next, tag); } }
/// <summary> /// More http://www.w3.org/TR/REC-xml/#NT-Attribute. /// </summary> /// <param name="c">The next input character.</param> /// <param name="q">The quote character.</param> /// <param name="tag">The current tag token.</param> XmlToken AttributeValue(Char c, Char q, XmlTagToken tag) { while (c != q) { if (c == Specification.EOF) throw Errors.Xml(ErrorCode.EOF); if (c == Specification.AMPERSAND) _stringBuffer.Append(GetEntity(CharacterReference(_src.Next))); else if (c == Specification.LT) throw Errors.Xml(ErrorCode.XmlLtInAttributeValue); else _stringBuffer.Append(c); c = _src.Next; } tag.SetAttributeValue(_stringBuffer.ToString()); return AttributeAfterValue(_src.Next, tag); }
/// <summary> /// More http://www.w3.org/TR/REC-xml/#NT-Attribute. /// </summary> /// <param name="c">The next input character.</param> /// <param name="tag">The current tag token.</param> XmlToken AttributeDoubleQuotedValue(Char c, XmlTagToken tag) { while (true) { if (c == Specification.DQ) { tag.SetAttributeValue(_stringBuffer.ToString()); return AttributeAfterValue(_src.Next, tag); } else if (c == Specification.AMPERSAND) { var value = CharacterReference(_src.Next); _stringBuffer.Append(GetEntity(value)); } else if (c == Specification.NULL) { RaiseErrorOccurred(ErrorCode.NULL); _stringBuffer.Append(Specification.REPLACEMENT); } else if (c == Specification.EOF) return XmlToken.EOF; else _stringBuffer.Append(c); c = _src.Next; } }
/// <summary> /// More http://www.w3.org/TR/REC-xml/#NT-Attribute. /// </summary> /// <param name="c">The next input character.</param> /// <param name="tag">The current tag token.</param> XmlToken AttributeName(Char c, XmlTagToken tag) { while (c.IsXmlName()) { _stringBuffer.Append(c); c = _src.Next; } var name = _stringBuffer.ToString(); if(!String.IsNullOrEmpty(tag.GetAttribute(name))) throw Errors.Xml(ErrorCode.XmlUniqueAttribute); tag.AddAttribute(name); if (c.IsSpaceCharacter()) { do c = _src.Next; while (c.IsSpaceCharacter()); } if (c == Specification.EQ) return AttributeBeforeValue(_src.Next, tag); throw Errors.Xml(ErrorCode.XmlInvalidAttribute); }
/// <summary> /// More http://www.w3.org/TR/REC-xml/#NT-Attribute. /// </summary> /// <param name="c">The next input character.</param> /// <param name="tag">The current tag token.</param> XmlToken AttributeBeforeValue(Char c, XmlTagToken tag) { while (c.IsSpaceCharacter()) c = _src.Next; if (c == Specification.DQ || c== Specification.SQ) { _stringBuffer.Clear(); return AttributeValue(_src.Next, c, tag); } throw Errors.Xml(ErrorCode.XmlInvalidAttribute); }
/// <summary> /// More http://www.w3.org/TR/REC-xml/#NT-Attribute. /// </summary> /// <param name="c">The next input character.</param> /// <param name="tag">The current tag token.</param> XmlToken AttributeBeforeName(Char c, XmlTagToken tag) { while (c.IsSpaceCharacter()) c = _src.Next; if (c == Specification.SOLIDUS) return TagSelfClosing(_src.Next, tag); else if (c == Specification.GT) return tag; else if (c == Specification.EOF) throw Errors.Xml(ErrorCode.EOF); if (c.IsXmlNameStart()) { _stringBuffer.Clear(); _stringBuffer.Append(c); return AttributeName(_src.Next, tag); } throw Errors.Xml(ErrorCode.XmlInvalidAttribute); }
/// <summary> /// More http://www.w3.org/TR/REC-xml/#NT-Attribute. /// </summary> /// <param name="c">The next input character.</param> /// <param name="tag">The current tag token.</param> XmlToken AttributeAfterValue(Char c, XmlTagToken tag) { if (c.IsSpaceCharacter()) return AttributeBeforeName(_src.Next, tag); else if (c == Specification.SOLIDUS) return TagSelfClosing(_src.Next, tag); else if (c == Specification.GT) return tag; throw Errors.Xml(ErrorCode.XmlInvalidAttribute); }
/// <summary> /// More http://www.w3.org/TR/REC-xml/#d0e2480. /// </summary> /// <param name="c">The next input character.</param> /// <param name="tag">The current tag token.</param> XmlToken TagSelfClosing(Char c, XmlTagToken tag) { tag.IsSelfClosing = true; if (c == Specification.GT) return tag; if (c == Specification.EOF) throw Errors.Xml(ErrorCode.EOF); throw Errors.Xml(ErrorCode.XmlInvalidName); }