“修复”格式错误的html以便在xsl转换中使用的最佳方法

时间:2013-09-18 12:47:57

标签: c# .net html5 xslt xslt-1.0

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

现在我将xsl转换应用于输出格式良好的xhtml5但包含格式错误的HTML的xml。

糟糕的html示例:

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

现在在我的情况下,我实际上并不关心html是否格式错误 - 我只关心我的结束标记与我的开始标记匹配,无论它们之间是什么。

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

  1. 充分清理html,使其不影响其他标记(最好是在变换本身内)
  2. 或以某种方式标记一个closetag,以便html5兼容的浏览器将其识别为匹配特定的开放标记,无论它们之间是否存在任何讨厌的标记。
  3. 2.我完全没有想法。我有一些想法1.例如调用像tidy这样的外部工具或使用.NET sgml解析器

    .NET xsl脚本(msxsl:script)是可以接受的,如果不受欢迎的话。

    示例来源:

    <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

2 个答案:

答案 0 :(得分:1)

是否可以使用第三方库? HTML Agility Pack(在NuGet上可用)可能是解决无效HTML的一部分,它也(根据网站)支持XSLT。

答案 1 :(得分: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"/>

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