0

我有一个输入 xml 文档,其中包含格式错误的 html,该 html 已经过 xml 编码。即 xml 文档本身在技术上是有效的。

现在我正在对输出格式正确的 xhtml5 但包含格式错误的 html 的 xml 应用 xsl 转换。

坏 html 的例子:

  • html 片段中的 html、head 和 body 标签。
  • 字体标签
  • 不匹配的引号
  • 未封闭的标签
  • 没有匹配打开的额外关闭标签
  • 以错误的顺序关闭标签(例如<b><u>text</b></u>

现在在我的情况下,我实际上并不关心 html 的格式是否错误——我只关心我的结束标签是否与我的开始标签匹配,而不管两者之间发生了什么。

所以我的问题是-最好的方法是什么

  1. 充分清理 html,使其不会影响其他标签(最好从转换本身内部)
  2. 或以某种方式标记一个closetag,以便与html5兼容的浏览器将其识别为匹配特定的打开标记,而不管其间可能存在任何讨厌的标记。

2.我完全没有想法。我对 1. 有几个想法,例如调用 tidy 之类的外部工具或使用 .NET sgml 解析器

msxsl:script如果不需要,可以接受.NET xsl 脚本 ( )。

示例来源:

<xml>
  &lt;b&gt;&lt;u&gt;bad html&lt;/b&gt;&lt;/u&gt;
<xml>

示例输出:

<div id="MyDiv">
  <b><u>bad html</b></u>
</div> <!-- this /div absolutly must match the opening div regardless of what might be in the bad html -->

还有哪些其他方法可用?

仅限 C#、VS2012、xslt 1.0

4

2 回答 2

1

可以接受使用第三方库吗?HTML Agility Pack (可在 NuGet上获得)可能会部分解决您的无效 HTML,并且它(根据网站)还支持 XSLT。

于 2013-09-18T13:59:01.193 回答
0

我选择使用 sgml 解析库并转换为有效的 xml。

我去了 Mind Touch 的图书馆:https ://github.com/MindTouch/SGMLReader

一旦编译并添加到 GAC,我就可以使用这个 xsl:

<msxsl:script language="C#" implements-prefix="myns">
  <msxsl:assembly name="SgmlReaderDll, Version=1.8.11.0, Culture=neutral, PublicKeyToken=46b2db9ca481831b"/>
    <![CDATA[
 public XPathNodeIterator SGMLStringToXml(string strSGML)
 {
 Sgml.SgmlReader sgmlReader = new Sgml.SgmlReader();
 sgmlReader.DocType = "HTML";
 sgmlReader.WhitespaceHandling = WhitespaceHandling.All;
 sgmlReader.CaseFolding = Sgml.CaseFolding.ToLower;
 sgmlReader.InputStream = new System.IO.StringReader(strSGML);

 // create document
 XmlDocument doc = new XmlDocument();
 doc.PreserveWhitespace = true;
 doc.XmlResolver = null;
 doc.Load(sgmlReader);
 return doc.CreateNavigator().Select("/*");
 }

 public string CurDir()
 {
 return (new System.IO.DirectoryInfo(".")).FullName;
 }
  ]]>

</msxsl:script>
<xsl:template match="node()" mode="PreventSelfClosingTags">
  <xsl:copy>
    <xsl:apply-templates select="@* | node()"/>
    <xsl:text> </xsl:text>
  </xsl:copy>
</xsl:template>
<xsl:template match="@*" mode="PreventSelfClosingTags">
  <xsl:copy>
    <xsl:apply-templates select="@* | node()"/>
  </xsl:copy>
</xsl:template>

并像这样使用它:

<xsl:apply-templates select="myns:SGMLStringToXml(.)/body/*" mode="PreventSelfClosingTags"/>

注意您必须使用XslCompiledTransform实例手动运行转换。该asp:xml控件不喜欢 DLL 引用。

于 2013-09-18T16:01:07.180 回答