最近做一个CMS,后台中需要使用在线编辑器对新闻进行编辑,然后发表。我用的在线编辑器是CKEditor+CKFinder。也许是我为了让CKEditor更本地化吧,改了很多。后来发现在CKEditor中对文字设置字体、颜色、字号大小时文字的<span>标签会出现N个的嵌套。我们知道,当span标签以嵌套方式出现的时候,它往往是以最后一个span标签的style方式显示的。也就是说外面的span标签的style就都被屏蔽了。这个让人有点郁闷~~.

      一开始想的解决办法是自己在其中查找span标签然后进行处理,但是想不好怎么解决嵌套的问题。后来琢磨使用正则表达式,也在网上查了很多资料。结果发现正则表达式真的复杂得头疼,而且其实也无法很好地处理嵌套标签的问题。

      一个偶然的机会~~(这句话听得很耳熟),我看到有人建议使用XmlDocument来进行处理。 我恍然大悟,我心里在呐喊:我的“病”有救了(还好面对的不是电线杆~~~~)。当然,使用XmlDocument之前你需要把CKEditor中的字符串处理一下,也就是符合xml规范。这个很简单,只要在外面加一个<div>标签作为根节点就成了。下面就贴上代码:

View Code 
 1     string content = "<div>" + BulletinBodyTxt.Text + "</div>";
 2     var doc = new XmlDocument();
 3     doc.LoadXml(content);
 4     XmlNodeList nodes = doc.GetElementsByTagName("span");
 5 
 6     string style = string.Empty, preText = string.Empty;
 7     foreach (XmlNode node in nodes)
 8     {
 9         if (node.InnerText == preText)
10         {
11             if (node.Attributes != null &&
12                 style.IndexOf(node.Attributes["style"].Value, StringComparison.Ordinal) < 0)
13                 style += node.Attributes["style"].Value;
14         }
15         else
16         {
17             if (node.Attributes != null) style = node.Attributes["style"].Value;
18             preText = node.InnerText;
19         }
20         if (node.Attributes != null)
21         {
22             node.Attributes["style"].Value = style;
23         }
24         else
25         {
26             node.Attributes.Append(CreateAttribute(node, "style", style));
27             //node.Attributes.Append()
28         }
29     }
30

这其中会有判断如果span标签里attribute为空的情况,使用了一个私有的CreateAttribute方法进行添加,这个方法的代码如下:

View Code 
 1     private XmlAttribute CreateAttribute(XmlNode node, string attributeName, string value)
 2     {
 3         try
 4         {
 5             XmlDocument doc = node.OwnerDocument;
 6             if (doc != null)
 7             {
 8                 XmlAttribute attr = doc.CreateAttribute(attributeName);
 9                 attr.Value = value;
10                 node.Attributes.SetNamedItem(attr);
11                 return attr;
12             }
13         }
14         catch (Exception err)
15         {
16             string desc = err.Message;
17         }
18         return null;
19

这样,这个问题就基本解决了。为什么说只是基本解决而不是根本解决?因为嵌套span还存在,只是把外层的style都写到最里层的style 里了。完美的做法是去掉嵌套,只保留一个span。这个因为时间原因就暂且留到日后解决吧。