/// <summary> /// 属性名を設定する。 /// 設定する値が null の場合は該当の属性は『削除』する /// </summary> /// <param name="attributeName"></param> /// <param name="attributeValue"></param> public void SetAttributes(string attributeName, string attributeValue) { string keyAttributeName = attributeName.ToLower(); if (_attrList == null) { ParseAttribute(); } if (attributeValue == null) { // 削除項目の検索 List<AttributeItem> delItemList = new List<AttributeItem>(); foreach (var attr in _attrList) { if (string.Equals(attr.Name, keyAttributeName,StringComparison.OrdinalIgnoreCase)) { delItemList.Add(attr); } } // 削除の実施 foreach (AttributeItem delItem in delItemList) { _attrList.Remove(delItem); } _attribute.Remove(keyAttributeName); } else { AttributeItem item = _attrList.FirstOrDefault(at => at.Name == keyAttributeName); if (item == null) { // 新規追加 if (_attrList.Count > 0) { AttributeItem spaceItem = new NullAttributeItem(" "); _attrList.Add(spaceItem); } item = new AttributeItem(); item.Name = keyAttributeName; _attrList.Add(item); } item.Value = attributeValue; } }
/// <summary> /// HTML タグを解析して属性の一覧を作成する。 /// </summary> /// <param name="RawString"></param> /// <returns></returns> private List<AttributeItem> ParseHtmlAttribute(string RawString, out AttributeItem tagAttr, out AttributeItem endTagAttr) { // <img src=test.gif > を解析して <img , {space} , attr:src=gif , {space} , > に分解する。 AttributeParser p = new AttributeParser(); List<AttributeItem> ans = p.ParseHtmlTag(RawString); // タグ部分を抽出して タグ名を取得する。 if (ans.Count >= 2) { AttributeItem tag = ans.FirstOrDefault(); AttributeItem endTag = ans.LastOrDefault(); string rawTagStr = ""; if (tag != null) { rawTagStr = tag.RawString; } if (rawTagStr.Length > 1 && rawTagStr[0] == '<') { // タグの開始 string strTag = rawTagStr.Substring(1).Trim().ToLower(); _tagName = strTag; } ans.Remove(tag); ans.Remove(endTag); tagAttr = tag; endTagAttr = endTag; } else { tagAttr = null; endTagAttr = null; } return ans; }
/// <summary> /// 属性を読む /// 空白:空白の終了まで /// 文字:属性=属性の値 /// 属性の値:"で始まれば " まで それ以外は空白または 終了タグ が出現するまで /// </summary> /// <returns></returns> private AttributeItem read_token() { if (ch == EOF) { currentItem = null; return null; } else if (char.IsWhiteSpace((char)ch)) { // 空白をすべて取り込む StringBuilder raw = new StringBuilder(); raw.Append((char)ch); read_ch(); while (ch != EOF) { if (char.IsWhiteSpace((char)ch)) { raw.Append((char)ch); } else { break; } read_ch(); } AttributeItem attr = new AttributeItem(raw.ToString()); currentItem = attr; return attr; } else if (ch == '>') { // 終了タグ read_ch(); AttributeItem attr = new AttributeItem(">"); currentItem = attr; return attr; } else { // = または 空白 または > が出現するまで attribute名 StringBuilder sbAttrName = new StringBuilder(); StringBuilder raw = new StringBuilder(); while (ch != EOF) { if (ch == '=') { break; } else if (char.IsWhiteSpace((char)ch)) { break; } else if (ch == '>') { break; } sbAttrName.Append((char)ch); raw.Append((char)ch); read_ch(); } StringBuilder sbValue = new StringBuilder(); if (ch == '=') { // 属性の値を取得 raw.Append((char)ch); read_ch(); if (ch == '"' || ch == '\'') { char find_char = (char)ch; sbValue.Append((char)ch); raw.Append((char)ch); read_ch(); // TODO: 文字列のエスケープ処理の対応が抜けている。 // 終了の " または ' が見つかるまで取り込み while (ch != EOF) { // 2009.10.10 属性の終了判定の間違い修正 Start //if (char.IsWhiteSpace((char)ch) || ch == '>' || ch == '<') //{ // break; //} //else // 2009.10.10 End if (ch == find_char) { sbValue.Append((char)ch); raw.Append((char)ch); read_ch(); break; } sbValue.Append((char)ch); raw.Append((char)ch); read_ch(); } } else { // 空白が見つかるまで取り込み while (ch != EOF) { if (char.IsWhiteSpace((char)ch) || ch == '>' ) // > が来たら終了 { break; } sbValue.Append((char)ch); raw.Append((char)ch); read_ch(); } } } AttributeItem attr = new AttributeItem(sbAttrName.ToString(), sbValue.ToString(), raw.ToString()); currentItem = attr; return attr; } }