AngleSharp解析为有效的HTML <script>和XML

时间:2018-03-28 15:20:50

标签: anglesharp

我正在使用AngleSharp为站点编写解析器,我最终需要获取XML。

&#xA;&#xA;

在xml中解析时,解析段脚本时出现问题,因为有这样的符号“&lt;%=”“%>”。&#xA;错误发生在编号为

&#xA;&#xA;&#xA;

的行上如何解决这种情况(我需要使用AngleSharp)?我试过不同的网站,结果是相同的

&#xA;&#xA;
  var config = Configuration.Default&#xA; .WithCss()&#XA; .WithDefaultLoader();&#XA; var address = Url.Create(“https://www.google.com/”);&#xA; var document = BrowsingContext.New(config).OpenAsync(address).GetAwaiter()。GetResult();&#xA;&#xA; XmlDocument xmlDocument = new XmlDocument();&#xA; var xDocument = new HtmlParser()。Parse(document.DocumentElement.InnerHtml);&#xA; var formatter = new AngleSharp.Xml.XmlMarkupFormatter();&#xA; var result = xDocument.ToHtml(formatter);&#xA; xmlDocument.LoadXml(结果); // 1&#XA;&#XA; var parserXML = new XmlParser()。Parse(document.DocumentElement.InnerHtml); // 2&#xA; xmlDocument.LoadXml(parserXML.ToHtml());&#XA;  
&#XA;

1 个答案:

答案 0 :(得分:0)

XML与HTML不兼容,即使它们非常相似。因此,一般来说,这是不可能的,但是,当您定义如何处理差异时,您可能会得出可能接受的结果。

在这种转换的核心,需要定义以下功能。我们只处理4种节点类型 - 不应该出现任何其他节点类型。为简单起见,我们丢弃任何命名空间元素或属性。

static XmlNode CreateNodeFrom(XmlDocument document, INode source)
{
    switch (source.NodeType)
    {
        case NodeType.Comment:
            return document.CreateComment(source.TextContent);
        case NodeType.Element:
            var original = (IElement)source;
            var element = document.CreateElement(original.LocalName);

            foreach (var attr in original.Attributes)
            {
                element.SetAttribute(attr.Name, attr.Value);
            }

            return element;
        case NodeType.Text:
            return document.CreateTextNode(source.TextContent);
        default:
            return null;
    }
}

该功能几乎全部来自树转换器:

static void AppendChildren(INode source, XmlNode target)
{
    var owner = target.OwnerDocument;

    foreach (var child in source.ChildNodes)
    {
        var node = CreateNodeFrom(owner, child);
        target.AppendChild(node);
        AppendChildren(child, node);
    }
}

所以我们只是走树并转换我们所看到的......改变原来的功能:

var config = Configuration.Default.WithCss().WithDefaultLoader();
var address = Url.Create("https://www.google.com/");
var document = BrowsingContext.New(config).OpenAsync(address).Result;
var xmlDocument = new XmlDocument();
var root = CreateNodeFrom(xmlDocument, document.DocumentElement);
xmlDocument.AppendChild(root);
AppendChildren(document.DocumentElement, root);

(我不知道为什么你使用了所有这些不同的解析器;解析器在文本级别上工作,但HTML和XML在文本级别上是不兼容的 - 所以让我们尝试在DOM级别上进行转换,是我们可以控制正在发生的事情的地方。

我删除了一些冗余并改进了您的async-&gt;同步桥(但我建议您删除.Result并使用await,即返回Task<XmlDocument>而不是XmlDocument)。

希望这有帮助!