11

汚い感じです。しかし、そうではないかもしれません... XML の記述に StringBuilder を使用しても問題ないでしょうか? 私の本能は、「これは間違っているように感じますが、余分なライブラリをロードしておらず、オーバーヘッドが XmlWriter を呼び出す余分なメソッドを実行していないため、おそらく非常にパフォーマンスが高いでしょう」と言っています。また、一般的にコードが少ないようです。XmlWriter の利点は何ですか?

これがどのように見えるかです。あなたのドメインに基づいて OpenSearch XML ドキュメントを作成しています。

public void ProcessRequest(HttpContext context)
{
    context.Response.ContentType = "text/xml";

    string domain = WebUtils.ReturnParsedSourceUrl(null); //returns something like www.sample.com
    string cachedChan = context.Cache[domain + "_opensearchdescription"] as String;

    if (cachedChan == null)
    {
        StringBuilder sb = new StringBuilder();
        sb.Append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
        sb.Append("<OpenSearchDescription xmlns=\"http://a9.com/-/spec/opensearch/1.1/\" xmlns:moz=\"http://www.mozilla.org/2006/browser/search/\">");
        sb.Append("    <ShortName>Search</ShortName>");
        sb.Append("    <Description>Use " + domain + " to search.</Description>");
        sb.Append("    <Contact>contact@sample.com</Contact>");
        sb.Append("    <Url type=\"text/html\" method=\"get\" template=\"http://" + domain + "/Search.aspx?q={searchTerms}\" />");
        sb.Append("    <moz:SearchForm>http://" + domain + "/Search.aspx</moz:SearchForm>");
        sb.Append("    <Image height=\"16\" width=\"16\" type=\"image/x-icon\">http://" + domain + "/favicon.ico</Image>");
        sb.Append("</OpenSearchDescription>");

        cachedChan = sb.ToString();

        context.Cache.Insert(domain + "_opensearchdescription", cachedChan, null, DateTime.Now.AddDays(14), TimeSpan.Zero);
    }

    context.Response.Write(cachedChan);
}

フォローアップ、〜2年後、 私が言おうとしていたことに気付きましたが、完全に言い損ねました.XMLクラスを使用してこのファイルを生成するコードの塊と、文字列を使用するだけの利点は何ですか? ありますか?これは(たとえば)ジョン・サンダーの例よりも悪いですか?

私はジム・シューベルトの方法を使い、「正しさ」を争うのではなく、「私はこれを読むことができ、理にかなっている」ことを選びました。できてよかったです。John Saunder の例には何の問題もありませんが、私が達成しようとしていたことに対して、それはかなり威圧的だと感じました。プラグマティズム?多分。

4

8 に答える 8

15

それは非常に間違っています。XML を理解する .NET API の 1 つを使用して XML を記述します。

を使用しても、 System.Xml.XmlWriter「余分なライブラリ」をロードすることによってパフォーマンスの問題が発生することはありません。


XML API を使用する理由は、XML の規則を理解しているからです。たとえば、要素内で引用する必要がある文字のセットと、属性内で引用する必要がある別のセットを知っています。

これはあなたの場合には問題にならないかもしれません:domain引用する必要がある文字が含まれていないことは確かです. より広い状況では、XML API に XML を実行させるのが最善です。XML API はその方法を知っているため、自分で実行する必要はありません。


LINQ to XML を使用して有効な XML を簡単に生成できる例を次に示します。

public static string MakeXml()
{
    XNamespace xmlns = "http://a9.com/-/spec/opensearch/1.1/";
    XNamespace moz = "http://www.mozilla.org/2006/browser/search/";
    string domain = "http://localhost";
    string searchTerms = "abc";
    var doc = new XDocument(
        new XDeclaration("1.0", "UTF-8", "yes"),
        new XElement(
            xmlns + "OpenSearchDescription",
            new XElement(xmlns + "ShortName", "Search"),
            new XElement(
                xmlns + "Description",
                String.Format("Use {0} to search.", domain)),
            new XElement(xmlns + "Contact", "contact@sample.com"),
            new XElement(
                xmlns + "Url",
                new XAttribute("type", "text/html"),
                new XAttribute("method", "get"),
                new XAttribute(
                    "template",
                    String.Format(
                        "http://{0}/Search.aspx?q={1}",
                        domain,
                        searchTerms))),
            new XElement(
                moz + "SearchForm",
                String.Format("http://{0}/Search.aspx", domain)),
            new XElement(
                xmlns + "Image",
                new XAttribute("height", 16),
                new XAttribute("width", 16),
                new XAttribute("type", "image/x-icon"),
                String.Format("http://{0}/favicon.ico", domain))));
    return doc.ToString(); // If you _must_ have a string
}
于 2010-04-09T20:45:27.453 に答える
2

行ごとに Append メソッドを呼び出す必要があるため、これには StringBuilder を使用しません。XmlWriter を使用できますが、パフォーマンスが低下することはありません。

次の手順を実行すると、生成される IL コードの量を減らすことができます。

private const string XML_TEMPLATE = @"<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<OpenSearchDescription xmlns=\"http://a9.com/-/spec/opensearch/1.1/\" xmlns:moz=\"http://www.mozilla.org/2006/browser/search/\">
    <ShortName>Search</ShortName>
    <Description>Use {0} to search.</Description>
    <Contact>contact@sample.com</Contact>
    <Url type=\"text/html\" method=\"get\" template=\"http://{0}/Search.aspx?q={searchTerms}\" />
    <moz:SearchForm>http://{0}/Search.aspx</moz:SearchForm>
    <Image height=\"16\" width=\"16\" type=\"image/x-icon\">http://{0}/favicon.ico</Image>
</OpenSearchDescription>";

そしてあなたの方法では:

    if (cachedChan == null)
    {
        cachedChan = String.Format(XML_TEMPLATE, domain);

        context.Cache.Insert(domain + "_opensearchdescription", 
               cachedChan, null, DateTime.Now.AddDays(14), TimeSpan.Zero);
    }

現在のメソッドは、 StringBuilder.Append() 呼び出しごとに新しい文字列を作成してから、そのメソッドを呼び出す必要があるため、これでうまくいくはずです。String.Format 呼び出しは 17 行の IL コードしか生成しませんが、StringBuilder は 8 行の ctor コードを生成し、その後 Append 呼び出しごとに 6 行を生成します。ただし、今日のテクノロジでは、余分な 50 行の IL は目立ちません。

于 2010-04-09T20:56:53.807 に答える
1

XML文字列自体を手動で書き込むこと自体に問題はありませんが、エラーが発生しやすくなります。これを行うための説得力のあるパフォーマンス上の理由がない限り(つまり、XMLフォーマットがボトルネックであることが測定されてわかった場合)、代わりにXMLクラスを使用します。デバッグと開発の時間を大幅に節約できます。

余談ですが、なぜ動的文字列操作をビルダー呼び出しと混合しているのですか?それ以外の:

sb.Append("    <Description>Use " + domain + " to search.</Description>"); 

これを試して:

sb.Append("    <Description>Use ").Append(domain).Append(" to search.</Description>");
于 2010-04-09T20:58:16.223 に答える
1

StringBuilderは使用しないでください。大幅に高速であると言う人は、実際のデータを提示していません。速度の違いは重要ではなく、あなたはあなたの前にメンテナンスの悪夢を抱くでしょう。

ルークを持っている:StringBuilder対XmlTextWriter

于 2010-04-09T21:00:49.147 に答える
1

うーん、これは微妙です。人生における他のすべての最適化と同様に、効率を得るために、抽象化の境界を破り、その代償を払います。

私の経験からすると、もちろんライブラリをロードするためではなく(どちらかといえば遅くなります)、文字列の割り当てを節約できるため、実際に大幅に高速です。どれくらい速くなったか正確には覚えていません、ごめんなさい。ガベージ コレクションのコストも節約できるため、プロファイラーで測定するのは困難です。

しかし、エンコーディングやエスケープに対処しなければならないとき、私を責めないでください。他に何があるかはわかりません。これらの XML をどこかに公開する前に、XML 標準を注意深く読むことを忘れないでください。

于 2010-04-09T20:47:11.207 に答える
0

ドメイン変数が「&」文字、またはエンコードする必要のある別の文字を返すことはありますか?時間をかけて防御的なプログラミングを行い、入力を検証することをお勧めします。

于 2010-04-09T20:58:32.227 に答える
0

あなたの腸は間違っています。XML を手書きするか、XmlWriter を使用するかに関係なく、XML を HttpResponse に送信する最も効率的な方法は、Response にテキストを直接追加することです。文字列全体を作成してから送信すると、リソースが無駄になります。

于 2010-04-09T20:48:02.397 に答える
-1

厳密に型指定されたオブジェクトを作成し、XmlSerialization クラスを使用して xml データを生成できます。

于 2010-04-09T20:47:26.377 に答える