最近做一个CMS,后台中需要使用在线编辑器对新闻进行编辑,然后发表。我用的在线编辑器是CKEditor+CKFinder。也许是我为了让CKEditor更本地化吧,改了很多。后来发现在CKEditor中对文字设置字体、颜色、字号大小时文字的<span>标签会出现N个的嵌套。我们知道,当span标签以嵌套方式出现的时候,它往往是以最后一个span标签的style方式显示的。也就是说外面的span标签的style就都被屏蔽了。这个让人有点郁闷~~.
一开始想的解决办法是自己在其中查找span标签然后进行处理,但是想不好怎么解决嵌套的问题。后来琢磨使用正则表达式,也在网上查了很多资料。结果发现正则表达式真的复杂得头疼,而且其实也无法很好地处理嵌套标签的问题。
一个偶然的机会~~(这句话听得很耳熟),我看到有人建议使用XmlDocument来进行处理。 我恍然大悟,我心里在呐喊:我的“病”有救了(还好面对的不是电线杆~~~~)。当然,使用XmlDocument之前你需要把CKEditor中的字符串处理一下,也就是符合xml规范。这个很简单,只要在外面加一个<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方法进行添加,这个方法的代码如下:
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。这个因为时间原因就暂且留到日后解决吧。