c# - 将HTML写入字符串

Translate

我有这样的代码。有没有一种方法可以使编写和维护变得更容易?使用C#.NET 3.5。

string header(string title)
{
    StringWriter s = new StringWriter();
    s.WriteLine("{0}","<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">");
    s.WriteLine("{0}", "<html>");
    s.WriteLine("<title>{0}</title>", title);
    s.WriteLine("{0}","<link rel=\"stylesheet\" type=\"text/css\" href=\"style.css\">");
    s.WriteLine("{0}", "</head>");
    s.WriteLine("{0}", "<body>");
    s.WriteLine("{0}", "");
}

我也可以这样写:

s.WriteLine("{0}", @"blah blah

many
new
lines
blah UHY#$&_#$_*@Y KSDSD<>\t\t\t\t\t\tt\t\t\\\t\t\t\t\\\h\th'\h't\th
hi
done"); 

它将起作用,但是我需要替换所有""".

This question and all comments follow the "Attribution Required."

所有的回答

lc.
Translate

您最好使用HtmlTextWriterXMLWriter比平原StringWriter。他们将为您进行转义,并确保文档格式正确。

这一页显示了使用HtmlTextWriter类,其要旨是:

StringWriter stringWriter = new StringWriter();

using (HtmlTextWriter writer = new HtmlTextWriter(stringWriter))
{
    writer.AddAttribute(HtmlTextWriterAttribute.Class, classValue);
    writer.RenderBeginTag(HtmlTextWriterTag.Div); // Begin #1

    writer.AddAttribute(HtmlTextWriterAttribute.Href, urlValue);
    writer.RenderBeginTag(HtmlTextWriterTag.A); // Begin #2

    writer.AddAttribute(HtmlTextWriterAttribute.Src, imageValue);
    writer.AddAttribute(HtmlTextWriterAttribute.Width, "60");
    writer.AddAttribute(HtmlTextWriterAttribute.Height, "60");
    writer.AddAttribute(HtmlTextWriterAttribute.Alt, "");

    writer.RenderBeginTag(HtmlTextWriterTag.Img); // Begin #3
    writer.RenderEndTag(); // End #3

    writer.Write(word);

    writer.RenderEndTag(); // End #2
    writer.RenderEndTag(); // End #1
}
// Return the result.
return stringWriter.ToString();
来源
Translate

当我用其他语言处理此问题时,我会将代码和HTML分开。就像是:

1.)创建一个HTML模板。采用[varname]占位符以标记替换/插入的内容。
2.)从数组或结构/映射/字典中填充模板变量

Write( FillTemplate(myHTMLTemplate, myVariables) ) # pseudo-code
来源
Translate

我知道您问过有关C#的问题,但是如果您愿意使用任何.Net语言,那么我强烈建议Visual Basic解决此确切问题。 Visual Basic具有称为XML文字的功能,该功能使您可以编写这样的代码。

Module Module1

    Sub Main()

        Dim myTitle = "Hello HTML"
        Dim myHTML = <html>
                         <head>
                             <title><%= myTitle %></title>
                         </head>
                         <body>
                             <h1>Welcome</h1>
                             <table>
                                 <tr><th>ID</th><th>Name</th></tr>
                                 <tr><td>1</td><td>CouldBeAVariable</td></tr>
                             </table>
                         </body>
                     </html>

        Console.WriteLine(myHTML)
    End Sub

End Module

这使您可以使用旧的ASP样式编写带有表达孔的纯HTML,并使代码具有更高的可读性。不幸的是,此功能不在C#中,但是您可以在VB中编写一个模块并将其添加为对C#项目的引用。

在Visual Studio中编写代码还可以对大多数XML文字和表达式整体进行适当的缩进。在VS2010中,表达孔的缩进效果更好。

来源
Translate

使用XDocument创建DOM,然后使用XmlWriter。这将为您提供一个极简明易懂的符号以及格式精美的输出。

采取以下示例程序:

using System.Xml;
using System.Xml.Linq;

class Program {
    static void Main() {
        var xDocument = new XDocument(
            new XDocumentType("html", null, null, null),
            new XElement("html",
                new XElement("head"),
                new XElement("body",
                    new XElement("p",
                        "This paragraph contains ", new XElement("b", "bold"), " text."
                    ),
                    new XElement("p",
                        "This paragraph has just plain text."
                    )
                )
            )
        );

        var settings = new XmlWriterSettings {
            OmitXmlDeclaration = true, Indent = true, IndentChars = "\t"
        };
        using (var writer = XmlWriter.Create(@"C:\Users\wolf\Desktop\test.html", settings)) {
            xDocument.WriteTo(writer);
        }
    }
}

这将产生以下输出:

<!DOCTYPE html >
<html>
    <head />
    <body>
        <p>This paragraph contains <b>bold</b> text.</p>
        <p>This paragraph has just plain text.</p>
    </body>
</html>
来源
Translate

你可以用System.Xml.Linq对象。他们是完全从旧的重新设计System.Xml从头开始构建XML的日子真令人讨厌。

除了我猜的文档类型,您还可以轻松地执行以下操作:

var html = new XElement("html",
    new XElement("head",
        new XElement("title", "My Page")
    ),
    new XElement("body",
        "this is some text"
    )
);
来源
Translate
return string.Format(@"<!DOCTYPE HTML PUBLIC ""-//W3C//DTD HTML 4.01//EN""      ""http://www.w3.org/TR/html4/strict.dtd"">
<html>
<title>{0}</title>
<link rel=""stylesheet"" type=""text/css"" href=""style.css"">
</head>
<body>
", title);
来源
Translate

最直接的方法是使用XmlWriter对象。这可以用来产生有效的HTML,并为您处理所有讨厌的转义序列。

来源
Translate

您可以使用T4模板用于从您的代码生成HTML(或任何HTML)。看到这个:http://msdn.microsoft.com/en-us/library/ee844259.aspx

来源
Translate

如果您要创建类似于在C#中创建XML文档的HTML文档,则可以尝试使用Microsoft的开源库,HTML敏捷包.

它提供了一个HtmlDocument对象,该对象的API与System.Xml.XmlDocument类。

来源
Translate

您可以使用ASP.NET在网页上下文之外生成HTML。这是一篇文章展示了如何做到这一点。

来源
Translate

您可以使用一些第三方开源库来生成强类型的已验证(X)HTML,例如CityLizard框架或Sharp DOM。

更新资料例如

html
    [head
        [title["Title of the page"]]
        [meta_(
            content: "text/html;charset=UTF-8",
            http_equiv: "Content-Type")
        ]
        [link_(href: "css/style.css", rel: "stylesheet", type: "text/css")]
        [script_(type: "text/javascript", src: "/JavaScript/jquery-1.4.2.min.js")]
    ]
    [body
        [div
            [h1["Test Form to Test"]]
            [form_(action: "post", id: "Form1")
                [div
                    [label["Parameter"]]
                    [input_(type: "text", value: "Enter value")]
                    [input_(type: "submit", value: "Submit!")]
                ]
            ]
            [div
                [p["Textual description of the footer"]]
                [a_(href: "http://google.com/")
                    [span["You can find us here"]]
                ]
                [div["Another nested container"]]
            ]
        ]
    ];
来源
Translate

这不是通用解决方案,但是,如果您的目的是拥有或维护电子邮件模板,则System.Web具有一个内置类,称为邮件定义。 ASP.NET成员资格控件使用此类来创建HTML电子邮件。

执行与上述相同的“字符串替换”操作,但是将它们全部打包到您的MailMessage中。

这是来自MSDN的示例:

ListDictionary replacements = new ListDictionary();
replacements.Add("<%To%>",sourceTo.Text);
replacements.Add("<%From%>", md.From);
System.Net.Mail.MailMessage fileMsg;
fileMsg = md.CreateMailMessage(toAddresses, replacements, emailTemplate, this); 
return fileMsg;
来源
Translate

随着ASP.net MVC中Razor的引入,用C#编写HTML的最佳方法是使用Razor Engine。

string templatePath = [email protected]"{Directory.GetCurrentDirectory()}\EmailTemplates"; 

IRazorLightEngine engine = EngineFactory.CreatePhysical(templatePath); 

var model = new Notification 
{ 
       Name = "Jone", 
       Title = "Test Email", 
       Content = "This is a test" 
}; 

string result = engine.Parse("template.cshtml", model); 

模板:

<h2>Dear @Model.Name, you have a notification.</h2> 

<h1>@Model.Title</h1> 
<p>@Model.Content</p> 

<p>Date:@DateTime.Now</p> 

有关完整示例,请参见这里

来源
Translate

您可以使用其Render方法和另一个属性来编写自己的类,以免在大量使用时造成麻烦,然后再使用HTMLWriter或xmlwriter。在asp.net页面中使用了此逻辑,您可以从webControl继承并覆盖渲染方法,如果您正在开发服务器端控件,那将非常有用。
这个可能是一个很好的例子。

问候

来源
Translate

这实际上取决于您要追求的目标,尤其取决于您真正需要提供什么样的性能。

我已经看到了用于强类型HTML开发(完整的控件模型,无论是ASP.NET Web控件还是类似控件)的令人称赞的解决方案,这些解决方案给项目增加了惊人的复杂性。在其他情况下,它是完美的。

按照C#领域的偏好,

  • ASP.NET Web控件
  • ASP.NET原语和HTML控件
  • XmlWriter和/或HtmlWriter
  • 如果进行具有HTML互操作性的Silverlight开发,请考虑使用强类型的东西,例如连结文字
  • StringBuilder和其他超级原语
来源
Translate

我写了这些课程,对我很有帮助。简单但实用。

public class HtmlAttribute
{
    public string Name { get; set; }
    public string Value { get; set; }

    public HtmlAttribute(string name) : this(name, null) { }

    public HtmlAttribute(
        string name,
        string @value)
    {
        this.Name = name;
        this.Value = @value;
    }

    public override string ToString()
    {
        if (string.IsNullOrEmpty(this.Value))
            return this.Name;

        if (this.Value.Contains('"'))
            return string.Format("{0}='{1}'", this.Name, this.Value);

        return string.Format("{0}=\"{1}\"", this.Name, this.Value);
    }
}

public class HtmlElement
{
    protected List<HtmlAttribute> Attributes { get; set; }
    protected List<object> Childs { get; set; }
    public string Name { get; set; }
    protected HtmlElement Parent { get; set; }

    public HtmlElement() : this(null) { }

    public HtmlElement(string name, params object[] childs)
    {
        this.Name = name;
        this.Attributes = new List<HtmlAttribute>();
        this.Childs = new List<object>();

        if (childs != null && childs.Length > 0)
        {
            foreach (var c in childs)
            {
                Add(c);
            }
        }
    }

    public void Add(object o)
    {
        var a = o as HtmlAttribute;
        if (a != null)
            this.Attributes.Add(a);
        else
        {
            var h = o as HtmlElement;
            if (h != null && !string.IsNullOrEmpty(this.Name))
            {
                h.Parent = this;
                this.Childs.Add(h);
            }
            else
                this.Childs.Add(o);
        }
    }

    public override string ToString()
    {
        var result = new StringBuilder();

        if (!string.IsNullOrEmpty(this.Name))
        {
            result.Append(string.Format("<{0}", this.Name));
            if (this.Attributes.Count > 0)
            {
                result.Append(" ");
                foreach (var attr in this.Attributes)
                {
                    result.Append(attr.ToString());
                    result.Append(" ");
                }

                result = new StringBuilder(result.ToString().TrimEnd(' '));
            }

            if (this.Childs.Count == 0)
            {
                result.Append(" />");
            }
            else
            {
                result.AppendLine(">");

                foreach (var c in this.Childs)
                {
                    var cParts = c.ToString().Split('\n');

                    foreach (var p in cParts)
                    {
                        result.AppendLine(string.Format("{0}", p));
                    }
                }

                result.Append(string.Format("</{0}>", this.Name));
            }
        }
        else
        {
            foreach (var c in this.Childs)
            {
                var cParts = c.ToString().Split('\n');

                foreach (var p in cParts)
                {
                    result.AppendLine(string.Format("{0}", p));
                }
            }
        }

        var head = GetHeading(this);

        var ps = result.ToString().Split('\n');
        return string.Join("\r\n", (from p in ps select head + p.TrimEnd('\r')).ToArray());
    }

    string GetHeading(HtmlElement h)
    {
        if (h.Parent != null)
            return "    ";
        else
            return string.Empty;
    }
}
来源
MMA
Translate

HSharp是用于轻松快速地分析诸如HTML之类的标记语言的库。安装:PM> Install-Package Obisoft.HSharp

        var Document = new HDoc(DocumentOptions.BasicHTML);
        Document["html"]["body"].AddChild("div");
        Document["html"]["body"]["div"].AddChild("a", new HProp("href", "/#"));
        Document["html"]["body"]["div"].AddChild("table");
        Document["html"]["body"]["div"]["table"].AddChildren(
         new HTag("tr"),
         new HTag("tr", "SomeText"),
         new HTag("tr", new HTag("td")));
        var Result = Document.GenerateHTML();
        Console.WriteLine(Result);

并输出:

<html>
<head>
<meta charset="utf-8"></meta><title>
Example </title>
</head>
<body>
<div>
<a href="/#"></a><table>
<tr></tr><tr>
SomeText </tr>
<tr>
<td></td></tr>
</table>
</div>
</body>
</html>
来源
Translate

我正在寻找某种看起来像jquery的东西,以在C#中生成dom(我不需要解析)。不幸的是,要找到一个轻量级的解决方案没有运气,所以我创建了一个从System.Xml.Linq.XElement继承的简单类。关键功能是,您可以像在javascript中使用jquery一样链接操作符,从而使操作更流畅。它的功能不完全,但是可以满足我的需要,如果有兴趣,我可以启动git。

public class DomElement : XElement
{
    public DomElement(string name) : base(name)
    {
    }

    public DomElement(string name, string value) : base(name, value)
    {
    }

    public DomElement Css(string style, string value)
    {
        style = style.Trim();
        value = value.Trim();
        var existingStyles = new Dictionary<string, string>();
        var xstyle = this.Attribute("style");
        if (xstyle != null)
        {
            foreach (var s in xstyle.Value.Split(';'))
            {
                var keyValue = s.Split(':');
                existingStyles.Add(keyValue[0], keyValue.Length < 2 ? null : keyValue[1]);
            }
        }

        if (existingStyles.ContainsKey(style))
        {
            existingStyles[style] = value;
        }
        else
        {
            existingStyles.Add(style, value);
        }

        var styleString = string.Join(";", existingStyles.Select(s => $"{s.Key}:{s.Value}"));
        this.SetAttributeValue("style", styleString);

        return this;
    }

    public DomElement AddClass(string cssClass)
    {
        var existingClasses = new List<string>();
        var xclass = this.Attribute("class");
        if (xclass != null)
        {
            existingClasses.AddRange(xclass.Value.Split());
        }

        var addNewClasses = cssClass.Split().Where(e => !existingClasses.Contains(e));
        existingClasses.AddRange(addNewClasses);

        this.SetAttributeValue("class", string.Join(" ", existingClasses));
        return this;
    }

    public DomElement Text(string text)
    {
        this.Value = text;
        return this;
    }

    public DomElement Append(string text)
    {
        this.Add(text);
        return this;
    }

    public DomElement Append(DomElement child)
    {
        this.Add(child);
        return this;
    }
}

样品:

void Main()
{
    var html = new DomElement("html")
        .Append(new DomElement("head"))
        .Append(new DomElement("body")
            .Append(new DomElement("p")
                .Append("This paragraph contains")
                .Append(new DomElement("b", "bold"))
                .Append(" text.")
                )
            .Append(new DomElement("p").Text("This paragraph has just plain text"))
            )
        ;

    html.ToString().Dump();

    var table = new DomElement("table").AddClass("table table-sm").AddClass("table-striped")
            .Append(new DomElement("thead")
                .Append(new DomElement("tr")
                    .Append(new DomElement("td").Css("padding-left", "15px").Css("color", "red").Css("color", "blue")
                        .AddClass("from-now")
                        .Append(new DomElement("div").Text("Hi there"))
                        .Append(new DomElement("div").Text("Hey there"))
                        .Append(new DomElement("div", "Yo there"))
                        )
                )
            )
        ;
    table.ToString().Dump();
}

以上代码的输出:

<html>
  <head />
  <body>
    <p>This paragraph contains<b>bold</b> text.</p>
    <p>This paragraph has just plain text</p>
  </body>
</html>
<table class="table table-sm table-striped">
  <thead>
    <tr>
      <td style="padding-left:15px;color:blue" class="from-now">
        <div>Hi there</div>
        <div>Hey there</div>
        <div>Yo there</div>
      </td>
    </tr>
  </thead>
</table>
来源
Leave a Reply
You must be logged in to post a answer.
关于作者