自定义类似XML的语法分析

时间:2018-04-18 08:07:38

标签: c# xml parsing

我试图从具有控制代码的游戏复制对话系统,控制代码是类似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语法,或者是否有其他类型的解析器可以用来实现我想要的?

3 个答案:

答案 0 :(得分:1)

您可以尝试使用HtmlAgilityPack

通过触发此命令Install-Package HtmlAgilityPack

来安装Nuget packge

以下示例将返回所有子节点。我没有将任何级别传递给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