6

XSLTを使用してHTML Web ページのコンテンツを変換する必要がありました 。したがって、私はSgmlReaderを使用し、以下に示すスニペットを作成しました (結局、これもXmlReaderだと思いました...)

XmlReader xslr = XmlReader.Create(new StringReader(
    "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
    "<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">" +
    "<xsl:output method=\"xml\" encoding=\"UTF-8\" version=\"1.0\" />" +
    "<xsl:template match=\"/\">" +
    "<XXX xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><xsl:value-of select=\"count(//br)\" /></XXX>" +
    "</xsl:template>" +
    "</xsl:stylesheet>"));

XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load(xslr);

using (SgmlReader html = new SgmlReader())
{
    StringBuilder sb = new StringBuilder();
    using (TextWriter sw = new StringWriter(sb))
    using (XmlWriter xw = new XmlTextWriter(sw))
    {
        html.InputStream = new StringReader(Resources.html_orig);
        html.DocType = "HTML";

        try
        {
            xslt.Transform(html, xw);
            string output = sb.ToString();
            System.Console.WriteLine(output);
        }
        catch (Exception exc)
        {
            System.Console.WriteLine("{0} : {1}", exc.GetType().Name, exc.Message);
            System.Console.WriteLine(exc.StackTrace);
        }
    }
}

それにもかかわらず、エラーメッセージが表示されます

NullReferenceException : Object reference not set to an instance of an object.
   at MS.Internal.Xml.Cache.XPathDocumentBuilder.Initialize(XPathDocument doc, IXmlLineInfo lineInfo, String baseUri, LoadFlags flags)
   at MS.Internal.Xml.Cache.XPathDocumentBuilder..ctor(XPathDocument doc, IXmlLineInfo lineInfo, String baseUri, LoadFlags flags)
   at System.Xml.XPath.XPathDocument.LoadFromReader(XmlReader reader, XmlSpace space)
   at System.Xml.XPath.XPathDocument..ctor(XmlReader reader, XmlSpace space)
   at System.Xml.Xsl.Runtime.XmlQueryContext.ConstructDocument(Object dataSource, String uriRelative, Uri uriResolved)
   at System.Xml.Xsl.Runtime.XmlQueryContext..ctor(XmlQueryRuntime runtime, Object defaultDataSource, XmlResolver dataSources, XsltArgumentList argList, WhitespaceRuleLookup wsRules)
   at System.Xml.Xsl.Runtime.XmlQueryRuntime..ctor(XmlQueryStaticData data, Object defaultDataSource, XmlResolver dataSources, XsltArgumentList argList, XmlSequenceWriter seqWrt)
   at System.Xml.Xsl.XmlILCommand.Execute(Object defaultDocument, XmlResolver dataSources, XsltArgumentList argumentList, XmlSequenceWriter results)
   at System.Xml.Xsl.XmlILCommand.Execute(Object defaultDocument, XmlResolver dataSources, XsltArgumentList argumentList, XmlWriter writer, Boolean closeWriter)
   at System.Xml.Xsl.XmlILCommand.Execute(XmlReader contextDocument, XmlResolver dataSources, XsltArgumentList argumentList, XmlWriter results)
   at System.Xml.Xsl.XslCompiledTransform.Transform(XmlReader input, XmlWriter results)

HTMLXMLに変換してから transform を適用することで、これを回避する方法を見つけましたが、次の理由から、これは非効率的な解決策です。

  1. 中間のXHTML出力は buffer に送られるため、余分なメモリが必要です
  2. 変換プロセスには追加のCPU処理が必要であり、同じ階層が 2 回走査されます (理論的には不必要です)。

したがって ( StackOverflowコミュニティは常に素晴らしい回答を提供してくれるのに対し、他のC#フォーラムでは完全にがっかりしていることを知っているので;o) HTMLを直接使用してXSL変換を実行するためのフィードバックと提案を探しています( SgmlReaderを別のものに置き換える必要がある場合でも)。同様のライブラリ)。

4

2 に答える 2

3

SgmlReaderクラスがクラスを拡張しているXmlReader場合でも、.XmlReader

SgmlReader技術的には、 が のサブクラスであることも意味がありませんXmlReader。単純に、SGML は XML のスーパーセットであり、サブセットではないからです。

変換の目的については書いていませんが、一般的にHTML Agility Packは HTML を操作するための優れたオプションです。

于 2010-11-30T15:41:42.533 に答える
1

の代わりにHTML Agility Packを使用してみましたSgmlReaderか? html をロードして、それに対して直接変換を実行できます。ただし、XML ドキュメントが内部で作成されているかどうかについては確信が持てません。そうではないように思えますが、試して破棄した変換方法とメモリと CPU の使用率を比較したいと思うでしょう。

//You already have your xslt loaded into var xslt...

HtmlDocument doc = new HtmlDocument();
doc.Load( ... );  //load your HTML doc, or use LoadXML from a string, etc  
xslt.Transform(doc, xw);

この質問も参照してください: HTML Agility パックの使用方法

于 2010-11-30T15:26:52.030 に答える