Mailkit:iTextSharpを使用してHtmlBodyをpdfに変換するXMLWorkerは "ドキュメントにはページがありません"

c# html-agility-pack itext mailkit xmlworker

質問

Mailkitを使ってメールサーバーから取得した電子メールのHtmlBodyを変換しようとしていますが、iTextSharpはhtmlを本当に気に入らないようです。

私のメソッドは、 "サンプル" htmlコードではうまくいきますが、htmlがもうhtmlでなくなったときにスローされるようなThe document has no pagesエラーメッセージは表示されません。

public void GenerateHtmlFromBody(UniqueId uid)
{
    var email = imap.Inbox.GetMessage(uid);
    Byte[] bytes;

    using (var ms = new MemoryStream())
    {
        using (var doc = new Document())
        {
            using (var writer = PdfWriter.GetInstance(doc, ms))
            {
                doc.Open();

                //Sample HTML and CSS
                var example_html = @"<p>This <em>is </em><span class=""headline"" style=""text-decoration: underline;"">some</span> <strong>sample <em> text</em></strong><span style=""color: red;"">!!!</span></p>";
                var example_css = @".headline{font-size:200%}";

                using (var srHtml = new StringReader(email.HtmlBody))
                {
                    //Parse the HTML
                    iTextSharp.tool.xml.XMLWorkerHelper.GetInstance().ParseXHtml(writer, doc, srHtml);
                }
                doc.Close();
            }
        }
        bytes = ms.ToArray();
    }
    var testFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "processedMailPdf.pdf");
    System.IO.File.WriteAllBytes(testFile, bytes);
}

私はMimeMessage.HtmlBodyとデバッグにアクセスしていMimeMessage.HtmlBody 、実際はhtmlのように見えます。

ここペーストビンへのリンクであるのを確認するためのHtmlBody MimeMessage私がここで文字の制限を打つため。

私は何が欠けていますか?ありがとう。

編集:私は(非難されている)HTMLWorkerを使ってみましたが、それは安定していません。それは1つの電子メールで動作しましたが、他のものでは動作しませんでした。もちろん、それは解決策ではありませんでしたが、最終的にMailkitから「何か」のpdfが生成されました。

受け入れられた回答

HtmlBody 2つの問題に直面しているようです:

  1. プレーンテキストかもしれません。
  2. [X] HTMLの場合、整形式ではありません

整形式のXMLではない文字列を扱っている可能性があるときはいつでも、 HtmlAgilityPackのようなパーサーを使って混乱を取り除くのが最善の方法です。上記の両方の問題をカバーするためにXPathを使用し、iText XML Workerを破るHtmlCommentNodeを削除するコメントに基づいてUPDATEDを使用する簡単なヘルパーメソッドがあります:

string FixBrokenMarkup(string broken)
{
    HtmlDocument h = new HtmlDocument()
    {
        OptionAutoCloseOnEnd = true,
        OptionFixNestedTags = true,
        OptionWriteEmptyNodes = true
    };
    h.LoadHtml(broken);

    // UPDATED to remove HtmlCommentNode
    var comments = h.DocumentNode.SelectNodes("//comment()");
    if (comments != null) 
    {
        foreach (var node in comments) { node.Remove(); }
    }

    return h.DocumentNode.SelectNodes("child::*") != null
        //                            ^^^^^^^^^^
        // XPath above: string plain-text or contains markup/tags
        ? h.DocumentNode.WriteTo()
        : string.Format("<span>{0}</span>", broken);
}

そして、完全性のために、PDFを生成するコード。上記のペーストビンのリンクを試して作業しています:

var fixedMarkup = FixBrokenMarkup(PASTEBIN);
// swap initialization to verify plain-text works too
// var fixedMarkup = FixBrokenMarkup("some text");

using (var stream = new MemoryStream())
{
    using (var document = new Document())
    {
        PdfWriter writer = PdfWriter.GetInstance(document, stream);
        document.Open();
        using (var stringReader = new StringReader(fixedMarkup))
        {
            XMLWorkerHelper.GetInstance().ParseXHtml(
                writer, document, stringReader
            );
        }
    }
    File.WriteAllBytes(OUTPUT, stream.ToArray());
}


ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ