/// <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;
            }
        }