我试图从具有控制代码的游戏复制对话系统,控制代码是类似HTML / XML的标签,用于指示文本泡泡的行为。例如,更改一段文本的颜色就像<co FF0000FF>Hello World!</co>
。文本中不需要这些控制代码,因此Hello <co FF0000FF>World!</co>
或简称Hello World
也应解析。
我尝试使其类似于XML以简化解析,但XML需要根级别标记才能成功解析,并且文本可能有也可能没有任何控制代码。例如,我能够使用XElement解析以下罚款。
string Text = "<co value=\"FF0000FF\">Hello World!</co>"
XElement.Parse(Text);
但是,以下因XMLException失败(&#34;根级别的数据无效。第1行,第1位。&#34;):
string Text = "Hello <co value=\"FF0000FF\">World!</co>"
XElement.Parse(Text);
处理此问题的好方法是什么?有没有办法处理字符串中的XML元素而不需要严格的XML语法,或者是否有其他类型的解析器可以用来实现我想要的?
答案 0 :(得分:1)
您可以尝试使用HtmlAgilityPack
通过触发此命令Install-Package HtmlAgilityPack
以下示例将返回所有子节点。我没有将任何级别传递给Descendants
,但您可以根据需要进一步添加更多代码。
它会解析您的自定义格式。
string Text = "Hello <co value=\"FF0000FF\">World!</co>";
Text = System.Net.WebUtility.HtmlDecode(Text);
HtmlDocument result = new HtmlDocument();
result.LoadHtml(Text);
List<HtmlNode> nodes = result.DocumentNode.Descendants().ToList();
答案 1 :(得分:1)
如果类似XML的片段和真实XML之间的唯一区别是缺少根元素,那么只需在解析之前将片段包装在虚拟根元素中:
parse("<dummy>" + fragment + "</dummy>")
如果存在其他差异,例如属性不在引号中,或者属性名称以数字开头,则XML解析器对您没什么用处,您需要自己编写。或者,如果你很幸运,像Validator.nu这样的HTML解析器可能会处理它。
答案 2 :(得分:0)
如果文本中的XML元素总是格式正确,那么您可以使用XML库来执行此操作。
您可以将文本包装在根元素中并使用XElement.Parse
并读取子节点,也可以使用一些较低级别的位来解析XML片段中的节点:
public static IEnumerable<XNode> Parse(string text)
{
var settings = new XmlReaderSettings
{
ConformanceLevel = ConformanceLevel.Fragment
};
using (var sr = new StringReader(text))
using (var xr = XmlReader.Create(sr, settings))
{
xr.MoveToContent();
while (xr.EOF == false)
{
yield return XNode.ReadFrom(xr);
}
}
}
像这样使用它:
foreach (var node in Parse("Hello <co value=\"FF0000FF\">World!</co>"))
{
Console.WriteLine($"{node.GetType().Name}: {node}");
}
输出这个:
XText: Hello
XElement: <co value="FF0000FF">World!</co>
有关正常工作的演示,请参阅this fiddle。