我有一个输入xml文档,其中包含经过xml编码的格式错误的html。 即xml文档本身在技术上是有效的。
现在我将xsl转换应用于输出格式良好的xhtml5但包含格式错误的HTML的xml。
糟糕的html示例:
<b><u>text</b></u>
)现在在我的情况下,我实际上并不关心html是否格式错误 - 我只关心我的结束标记与我的开始标记匹配,无论它们之间是什么。
所以我的问题是 - 什么是最好的方法
2.我完全没有想法。我有一些想法1.例如调用像tidy这样的外部工具或使用.NET sgml解析器
.NET xsl脚本(msxsl:script
)是可以接受的,如果不受欢迎的话。
示例来源:
<xml>
<b><u>bad html</b></u>
<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
答案 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引用。