c# - Napisz HTML do ciągu

Translate

Mam taki kod. Czy istnieje sposób, aby ułatwić pisanie i konserwację? Korzystanie z 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}", "");
}

Mógłbym też po prostu napisać:

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"); 

Będzie działać, ale muszę wymienić wszystko"z"".

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

Wszystkie odpowiedzi

lc.
Translate

Prawdopodobnie lepiej będzie, jeśli użyjesz rozszerzeniaHtmlTextWriterlubXMLWriterniż zwykłyStringWriter. Zadbają o twoją ucieczkę, a także upewnią się, że dokument jest poprawny.

Ta stronapokazuje podstawy korzystania zHtmlTextWriterklasa, której istotą jest:

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();
Źródło
Translate

Kiedy zajmuję się tym problemem w innych językach, wybieram oddzielenie kodu i HTML. Coś jak:

1.) Utwórz szablon HTML. posługiwać się[varname]symbole zastępcze do oznaczania zastąpionej / wstawionej zawartości.
2.) Wypełnij zmienne szablonu z tablicy lub struktury / mapowania / słownika

Write( FillTemplate(myHTMLTemplate, myVariables) ) # pseudo-code
Źródło
Translate

Wiem, że pytałeś o C #, ale jeśli chcesz użyć dowolnego języka .Net, bardzo polecam Visual Basic do tego konkretnego problemu. Visual Basic ma funkcję o nazwie XML Literals, która umożliwia pisanie takiego kodu.

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

Pozwala to na pisanie prostego kodu HTML z lukami w wyrażeniach w starym stylu ASP i sprawia, że kod jest bardzo czytelny. Niestety tej funkcji nie ma w C #, ale możesz napisać pojedynczy moduł w VB i dodać go jako odniesienie do projektu C #.

Pisanie w programie Visual Studio umożliwia również prawidłowe wcięcie większości literałów XML i całych wyrażeń. Wcięcie dla otworów ekspresyjnych jest lepsze w VS2010.

Źródło
Translate

UżyjXDocumentaby utworzyć DOM, a następnie wypisz go za pomocą plikuXmlWriter. To da ci cudownie zwięzłą i czytelną notację, a także ładnie sformatowane wyjście.

Weź ten przykładowy program:

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);
        }
    }
}

Spowoduje to wygenerowanie następującego wyniku:

<!DOCTYPE html >
<html>
    <head />
    <body>
        <p>This paragraph contains <b>bold</b> text.</p>
        <p>This paragraph has just plain text.</p>
    </body>
</html>
Źródło
Translate

Możesz użyćSystem.Xml.Linqobiekty. Zostały całkowicie przeprojektowane ze staregoSystem.Xmldni, które sprawiły, że konstruowanie XML od podstaw było naprawdę denerwujące.

Poza typem dokumentu, jak sądzę, możesz łatwo zrobić coś takiego:

var html = new XElement("html",
    new XElement("head",
        new XElement("title", "My Page")
    ),
    new XElement("body",
        "this is some text"
    )
);
Źródło
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);
Źródło
Translate

Najprostszym sposobem jest użycie obiektu XmlWriter. Można to wykorzystać do stworzenia prawidłowego kodu HTML i zajmie się wszystkimi nieprzyjemnymi sekwencjami ucieczki.

Źródło
Translate

Możesz użyćSzablony T4do generowania HTML (lub dowolnego) z twojego kodu. Zobacz:http://msdn.microsoft.com/en-us/library/ee844259.aspx

Źródło
Translate

Jeśli chcesz utworzyć dokument HTML podobny do tego, jak utworzyłbyś dokument XML w C #, możesz wypróbować bibliotekę open source firmy Microsoft,Pakiet Agility HTML.

Udostępnia obiekt HtmlDocument, który ma bardzo podobny interfejs API doSystem.Xml.XmlDocumentklasa.

Źródło
Translate

Możesz użyć ASP.NET do generowania kodu HTML poza kontekstem stron internetowych.Oto artykułto pokazuje, jak można to zrobić.

Źródło
Translate

Możesz użyć niektórych bibliotek open source innych firm do wygenerowania silnie wpisanego zweryfikowanego (X) HTML, takiego jakCityLizard Frameworklub Sharp DOM.

AktualizacjaNa przykład

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"]]
            ]
        ]
    ];
Źródło
Translate

Nie jest to jednak ogólne rozwiązanie, jeśli jednak Twoim celem jest posiadanie lub utrzymywanie szablonów wiadomości e-mail, wówczas System.Web ma wbudowaną klasę o nazwieMailDefinition. Ta klasa jest używana przez kontrolki członkostwa ASP.NET do tworzenia wiadomości e-mail w formacie HTML.

Wykonuje ten sam rodzaj „ciągów znaków zastępujących” rzeczy, jak wspomniano powyżej, ale pakuje to wszystko do wiadomości MailMessage.

Oto przykład z 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;
Źródło
Translate

Wraz z wprowadzeniem Razor w ASP.net MVC najlepszym sposobem pisania kodu HTML w języku C # jest użycie 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); 

Szablon:

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

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

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

Aby zapoznać się z pełną próbką, zobacztutaj

Źródło
Translate

Możesz napisać własne klasy z jego metodą Render i innymi atrybutami, aby uniknąć wielkiego bałaganu, jeśli często go używasz, a następnie użyć również HTMLWriter lub xmlwriter. Ta logika jest używana na stronach asp.net, można dziedziczyć z webControl i zastąpićmetoda renderowania, co jest świetne, jeśli tworzysz elementy sterujące po stronie serwera.
Tomoże być dobrym przykładem.

pozdrowienia

Źródło
Translate

To naprawdę zależy od tego, do czego zmierzasz, a konkretnie od tego, jaki rodzaj wydajności naprawdę chcesz zaoferować.

Widziałem godne podziwu rozwiązania do tworzenia mocno typizowanych HTML (kompletne modele kontrolne, czy to ASP.NET Web Controls, czy podobne), które po prostu dodają niesamowitej złożoności do projektu. W innych sytuacjach jest doskonały.

W kolejności preferencji w świecie C #,

  • ASP.NET Web Controls
  • Prymitywy ASP.NET i kontrolki HTML
  • XmlWriter i / lub HtmlWriter
  • Jeśli tworzysz program Silverlight z interoperacyjnością HTML, rozważ coś silnie wpisanego, takiego jaktekst linku
  • StringBuilder i inne super prymitywy
Źródło
Translate

Napisałem te zajęcia, które dobrze mi służyły. To proste, ale pragmatyczne.

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;
    }
}
Źródło
MMA
Translate

HSharp to biblioteka używana do łatwej i szybkiej analizy języka znaczników, takiego jak HTML. Zainstalować: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);

i wyjście:

<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>
Źródło
Translate

Szukałem czegoś, co wyglądało jak jquery do generowania domeny w C # (nie muszę analizować). Niestety nie udało się znaleźć lekkiego rozwiązania, więc stworzyłem tę prostą klasę, która jest dziedziczona po System.Xml.Linq.XElement. Kluczową cechą jest to, że możesz połączyć operatora tak, jak podczas używania jquery w javascript, aby był bardziej płynny. Nie jest w pełni funkcjonalny, ale robi to, czego potrzebuję i jeśli jest zainteresowanie, mogę rozpocząć gita.

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;
    }
}

Próba:

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();
}

wyjście z powyższego kodu:

<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>
Źródło
Leave a Reply
You must be logged in to post a answer.
O autorze