65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 MariGold.OpenXHTML 和 AngleSharp 将 HTML 转换为 Open XML Word 文档

starIconstarIconstarIconstarIconstarIcon

5.00/5 (1投票)

2017年12月15日

CPOL

4分钟阅读

viewsIcon

16397

downloadIcon

381

逐步指南,介绍如何将 AngleSharp HTML 解析器集成到 MariGold.OpenXHTML 中

引言

MariGold.OpenXHTML 是一个开源的 GitHub,用于将 HTML 文档转换为 Open XML Word 文档。它使用内部 HTML 解析器来读取 HTML 元素。此 HTML 解析器可以完全替换为您喜欢的 HTML 解析器。在这里,我将演示如何使用流行的 AngleSharp HTML 解析器来完成此操作。

Using the Code

MariGold.OpenXHTML 依赖于两个接口来读取 HTML。我们只需要为这两个接口创建实现。这些接口是:

MariGold.HtmlParser.IHtmlNode - 这只是 HTML 元素的容器。我们的自定义 HTML 解析器使用它来创建 HTML 节点元素的层次结构,以便在 MariGold.OpenXHTML 中进行处理。
MariGold.OpenXHTML.IParser - 用于实现自定义 HTML 解析器。我们将 AngleSharp 集成到其中,以处理 HTML 字符串

打开 Visual Studio 并创建一个控制台应用程序项目。在根目录下创建一个名为 source.html 的文件,并填入您想要转换的 HTML 内容。选择此 HTML 文件的属性,并将 **复制到输出目录** 属性设置为 **始终复制**,以便我们的演示可以处理该文件在 bin 文件夹中可用。

下一步是安装 MariGold.OpenXHTML nuget 包。从 工具 -> NuGet 包管理器 -> 包管理器控制台执行命令 Install-Package MariGold.OpenXHTML。这将把以下包安装到您的项目中。MariGold.HtmlParser 是默认的 HTML 解析器。在这里,我们将只使用这个库中的一个接口来进行我们的自定义实现。

  • DocumentFormat.OpenXml
  • MariGold.HtmlParser
  • MariGold.OpenXHTML

实现 MariGold.HtmlParser.IHtmlNode

创建一个名为 AngleNode 的类,并让它继承自 MariGold.HtmlParser.IHtmlNode。在此类中创建一个构造函数,接受一个 AngleSharp.Dom.INode 类型的对象,并将其存储在一个 private 变量中。我们将使用此节点来提取 IHtmlNode 所需的属性。

private readonly INode node;

internal AngleNode(INode node)
{
    this.node = node;
}

这些属性用于 MariGold.OpenXHTML 创建等效的 Open XML 元素属性。并非 IHtmlNode 的所有属性都在 MariGold.OpenXHTML 中使用。下面列出了必需的属性。您可以在随附的示例项目中找到这些属性的实现细节。

  • Attributes - 所有 HTML 属性的字典
  • Children - 包含文本元素的子元素的 IEnumerable 集合
  • HasChildren - 一个布尔属性,用于检查元素是否具有子元素
  • InnerHtml - 元素的内部 HTML,以 string 格式表示。主要用于获取文本元素的内容
  • IsText - 用于识别节点是文本元素还是非文本元素
  • Next - 下一个同级元素。如果没有这样的元素,则为 null
  • Parent - 父元素。如果是根元素,则为 null
  • Previous - 前一个同级元素。如果没有这样的元素,则为 null
  • Styles - 所有样式属性的字典
  • Tag - HTML 元素的标签名

实现 MariGold.OpenXHTML.IParser

此接口位于 MariGold.OpenXHTML 命名空间。它负责解析 HTML 文档。它包含两个属性和两个方法。为了实现这些属性和方法,请创建一个名为 AngleParser 的类,并让它继承自 IParser。如下所示实现这两个属性。这些属性不需要包含任何逻辑。它们只是 HTML 文档中任何相对或无协议 URL 引用的基本 URL 和 URI Schema 的容器。

public string BaseURL { get; set; }
public string UriSchema { get; set; }

接下来,我们将实现 CalculateRelativeChildFontSize 方法。有时,MariGold.OpenXHTML 需要计算某些 HTML 元素的相对字体大小。有关更多信息,请参阅 GitHub 中的 HTML 解析部分。如果您不想重新处理此问题,可以使用默认实现。就像下面的方法一样。

public decimal CalculateRelativeChildFontSize(string parentFontSize, string childFontSize)
{
    return MariGold.HtmlParser.CSSUtility.CalculateRelativeChildFontSize
                                             (parentFontSize, childFontSize);
}

接下来,在 AngleParser 中创建一个构造函数,接受一个 HTML 字符串。此构造函数会将 HTML 字符串加载到一个 private 变量中,以便稍后处理。

private readonly string html;

public AngleParser(string html)
{
    this.html = html;
}

IParser 接口中的最后一个方法是 FindBodyOrFirstElement 方法。这是我们自定义解析器实现的核心方法。在实现此方法之前,请使用 NuGet 包管理器安装 AngleSharp。然后,在 AngleParser 中编写一个 private 方法来读取 HTML 字符串,并使用 AngleSharp 获取 HTML body 元素。

private IHtmlElement ParseBody()
{
    var parser = new AngleSharp.Parser.Html.HtmlParser(Configuration.Default.WithCss());
    var doc = parser.Parse(html);
    return doc.Body;
}

FindBodyOrFirstElement 方法应返回 HTML Body 元素的 IHtmlNode 类型实现,如果 HTML 字符串中缺少 body 元素,则返回根元素。

public MariGold.HtmlParser.IHtmlNode FindBodyOrFirstElement()
{
    return new AngleNode(ParseBody());
}

现在,自定义 HTML 解析器实现已准备好集成到 MariGold.OpenXHTML 中。在控制台应用程序的主方法中编写以下代码。AngleParsersource.html 读取 HTML 字符串,并在 WordDocument 类中进行解析。

WordDocument doc = new WordDocument("sample.docx");

using (StreamReader sr = new StreamReader("source.html"))
{
    doc.Process(new AngleParser(sr.ReadToEnd()));
}

doc.Save();
© . All rights reserved.