我的原始问题是我正在尝试将包含html标记的字符串序列化为XML元素。
hello <a href="world.php">World</a>, this
is
a nice
test
<ul>
<li>to demonstrate my issue</li>
<li>and find a solution</li>
</ul>
但是,我有2个问题
<小时/> 这个字符串看起来像如上所述,但html不完全正确(没有
<p>
标签,没有<br>
标签)。
现在我想用p或br标签替换换行符。我看了here并使用了建议的解决方案:
string result = "<p>" + text
.Replace(Environment.NewLine + Environment.NewLine, "</p><p>")
.Replace(Environment.NewLine, "<br />")
.Replace("</p><p>", "</p>" + Environment.NewLine + "<p>") + "</p>";
但是,这并非在所有情况下都生成有效的html。在上面的示例中,它会在<br />
代码之间创建<li>
或在<ul>
代码中生成<p>
代码 - 这两种情况都是不允许的。
目标是获得如下结果(换行符只是为了更好的可读性而且无关紧要)
<p>hello <a href="world.php">World</a>, this</p>
<p>is<br/>
a nice<br/>
test<br/></p>
<ul>
<li>to demonstrate my issue</li>
<li>and find a solution</li>
</ul>
您是否有任何建议如何使用string.Replace,Regex或更好的解决方案(HtmlDocument)来解决这个问题?
请注意:我对反序列化没有影响,XML输出由I工具评估我没有影响,它必须是UTF-8编码。
谢谢!
编辑:明确区分了2个问题
EDIT2:对反序列化没有影响
EDIT3:添加了目标输出
答案 0 :(得分:3)
您要做的是实现一个"tag soup parser",它将可能是或不是HTML的文本作为输入并将其转换为HTML解析器可以处理的有效DOM。
你不想重新发明这个轮子,绝对不是简单的字符串替换。有关提示,请参阅How to parse bad html?。
或者您可以对输入HTML进行编码,使其不会干扰您尝试将其放入的XML,like a CDATA section或base64-encoding输入也足够。不要使用“实体编码”,因为您的XML解析器会抱怨不是XML实体的HTML实体。
答案 1 :(得分:0)
我必须做类似的事情(确保第三方内容具有有效的HTML)。如果我这样做,我会做以下事情:
1)用HTML换行符替换换行符
string result = text.Replace(Environment.NewLine, "<br />");
2)使用HTMLAgility包修复任何无效的HTML
var doc = new HtmlDocument();
HtmlNode.ElementsFlags["p"] = HtmlElementFlag.Closed;
doc.OptionFixNestedTags = false;
doc.LoadHtml(result);
if (doc.ParseErrors.Count() > 0)
{
// throw error
}else{
// get fixed html
result= doc.DocumentNode.OuterHtml;
}