4

手早く汚れた構成エディターを起動して実行する必要があります。流れは次のようになります。

構成 (サーバー上の POCO) は XML にシリアライズされます。
この時点で、XML は整形式です。構成は、XElements の Web サーバーに送信されます。
Web サーバーでは、XML (Yes, All of IT) が編集用のテキストエリアにダンプされます。
ユーザーは Web ページで XML を直接編集し、[送信] をクリックします。
応答では、XML 構成の変更されたテキストを取得します。この時点で、すべてのエスケープは Web ページに表示するプロセスによって元に戻されています。
文字列を XML オブジェクト (XmlElement、XElement など) に読み込もうとしました。カブーム。

問題は、シリアライゼーションが属性文字列をエスケープすることですが、これは途中の変換で失われます。

たとえば、正規表現を持つオブジェクトがあるとします。Web サーバーに関する構成は次のとおりです。

<Configuration>
  <Validator Expression="[^&lt;]" />
</Configuration>

したがって、これをテキストエリアに配置すると、ユーザーには次のように表示されます。

<Configuration>
  <Validator Expression="[^<]" />
</Configuration>

そのため、ユーザーはわずかな変更を加えて、変更を送信します。Web サーバーでは、応答文字列は次のようになります。

<Configuration>
  <Validator Expression="[^<]" />
  <Validator Expression="[^&]" />
</Configuration>

そのため、ユーザーは別のバリデーターを追加しましたが、現在、両方に不正な文字を含む属性があります。これを任意の XML オブジェクトにロードしようとすると、テキスト文字列内で < と & が有効でないため、例外がスローされます。I CANNOT CANNOT CANNOT CANNOT どんな種類のエンコーディング関数も使用できません。

var 結果 = Server.HttpEncode(editedConfig);

結果は

&lt;Configuration&gt;
  &lt;Validator Expression="[^&lt;]" /&gt;
  &lt;Validator Expression="[^&amp;]" /&gt;
&lt;/Configuration&gt;

これは有効な XML ではありません。これをあらゆる種類の XML 要素にロードしようとすると、落下する金床にぶつかります。私はアンビルが落ちるのが好きではありません。

SO、疑問が残ります...この文字列 XML を XML オブジェクトに解析できるようにする唯一の方法は、正規表現の置換を使用することですか? ロード時に「制約をオフにする」方法はありますか? これをどのように回避しますか?


有効な回答があるとは思わないので、最後の回答とこれを wiki 化します。

テキストエリアに配置した XML は有効で、エスケープされた XML です。1) テキスト領域に配置する 2) クライアントに送信する 3) クライアントに表示する 4) フォームを送信する 5) サーバーに送信する 6) フォームから値を取得する 削除するありとあらゆる逃避。

もう一度言いますが、私は何もエスケープしていません。ブラウザに表示するだけでこうなる!

熟考すべきこと: そもそもこの非エスケープが起こらないようにする方法はありますか? ほぼ有効な XML を安全な方法で "クリーン" にする方法はありますか?


この質問には賞金があります。報奨金を集めるために、正規表現を使用して属性値を手動でエスケープする必要がなく、ユーザーが属性をエスケープする必要がないサードパーティ/オープンソース ツールを使用せずに、ブラウザ ウィンドウで VALID XML を編集する方法を示してください。ラウンドトリップ時に失敗しません(&amp;amp;etc;)

4

8 に答える 8

7

うーん… <em>どのようにシリアル化しますか? 通常、XML シリアライザーが無効な XML を生成することはありません。

/EDIT 更新への対応:無効な XML をユーザーに表示して編集させないでください。代わりに、適切にエスケープされた XML を TextBox に表示します。壊れた XML を修復するのは楽しいことではありません。XML を有効なエスケープ形式で表示/編集しない理由はありません。

XML を TextBox に表示する方法を教えてください。ある時点で意図的に XML のエスケープを解除しているようです。

/EDIT あなたの最新のコメントに応えて: そうです、明らかに、それは HTML を含むことができるからです。XML を HTML ページに書き出す前に、XML を適切にエスケープする必要があります。つまり、XML全体を意味します。したがって、この:

<foo mean-attribute="&lt;">

これになります:

&lt;foo mean-attribute="&amp;&lt;"&gt;
于 2008-10-28T18:22:35.263 に答える
5

もちろん、テキストエリア内にエンティティ参照を配置すると、エスケープされません。テキストエリアは魔法ではありません。 &escape; する必要があります。他のすべての要素と同じように、それらに入れるすべてのもの。ブラウザはテキストエリアに生の '<' を表示することがありますが、それは間違いを正そうとしているためです。

したがって、編集可能な XML をテキストエリアに配置する場合、有効な XML にするために属性値を一度エスケープする必要があります。次に、XML 全体を再度エスケープして有効な HTML にする必要があります。ページに表示する最終的なソースは次のようになります。

<textarea name="somexml">
    &lt;Configuration&gt;
        &lt;Validator Expression="[^&amp;lt;]" /&gt;
        &lt;Validator Expression="[^&amp;amp;]" /&gt;
    &lt;/Configuration&gt;
</textarea>

質問は、textarea 要素のコンテンツ モデルの誤解に基づいています。バリデーターはすぐに問題を見つけたでしょう。

ETA re comment: さて、どのような問題が残っていますか? それは連載側の問題です。あとはそれを解析して戻すだけです。そのためには、ユーザーが整形式の XML を作成できると想定する必要があります。

属性値でエスケープされていない「<」や「&」などのエラーを許可するために、整形式でない XML を解析しようとすると、XML の本来の動作方法に完全に反する損失になります。ユーザーが整形式の XML を書くことを信頼できない場合は、改行で区切られた単純な正規表現文字列のリストなど、より簡単な非 XML インターフェイスをユーザーに提供してください。

于 2008-10-29T12:46:22.117 に答える
1

注:あなたが説明したように、Firefox(私のテストでは)はテキスト領域でエスケープ解除しません。具体的には、このコード:

<textarea cols="80" rows="10" id="1"></textarea>

<script>
elem = document.getElementById("1");

elem.value = '\
<Configuration>\n\
  <Validator Expression="[^&lt;]" />\n\
</Configuration>\
'
alert(elem.value);
</script>

次のように警告され、変更されていないユーザーに表示されます。

<Configuration>
  <Validator Expression="[^&lt;]" />
</Configuration>

したがって、おそらく 1 つの (実行不可能な?) 解決策は、ユーザーが Firefox を使用することです。


あなたの質問の 2 つの部分が明らかになったようです。

表示する1 つの XML がエスケープされていません。

たとえば、" &lt;" は "<" としてエスケープされません。ただし、「<」も「<」としてエスケープされていないため、情報が失われ、元に戻すことはできません。

解決策の 1 つは、すべての " &" 文字をエスケープして、" " を " &lt;"にすること&amp;lt;です。これは、テキストエリアによって " " としてエスケープされません&lt;。読み返すと元通りになる。(テキストエリアが実際に文字列を変更すると仮定していますが、報告どおりにFirefoxが動作していないため、これを確認できません)

もう 1 つの解決策 (既に述べたように思います) は、カスタム テキスト エリアを作成/購入/借用することです (単純であれば悪くはありませんが、すべての編集キー、ctrl-C、ctrl-shift-left などがあります)。

2ユーザーがわざわざエスケープする必要がないようにしたい。

あなたは脱出地獄にいます:

正規表現の置換はほとんど機能します...しかし、ユーザーが(正当に、指定した条件の範囲内で)入力する可能性がある場合、どのようにして最後の引用符( ")を確実に検出できますか?

<Configuration>
  <Validator Expression="[^"<]" />
</Configuration>

正規表現構文の観点から見ると、最後の " が正規表現の一部なのか、それとも末尾なのかを判断することもできません。通常、正規表現構文では、明示的なターミネータを使用してこの問題を解決します。例:

/[^"<]/

ユーザーがこの構文を (ターミネータと共に) 使用し、パーサーを作成した場合、正規表現がいつ終了したかを判断できるため、次の " 文字は正規表現の一部ではなく、XML の一部であり、したがって、どの部分をエスケープする必要がありますか? 私はあなたがこれをすべきだと言っているのではありません! 理論的には可能だと言っているのです.

ところで: 要素内のテキストについても同じ問題が発生します。以下は、あなたが与えた条件の範囲内で正当ですが、同じ解析問題があります:

<Configuration>
  <Expression></Expression></Expression>
</Configuration>

「任意のテキスト」を許可する構文の基本的なルールは、末尾を認識できるように、区切り文字をエスケープする必要があることです (例: " または <)。ほとんどの構文は、利便性/不便さのために、他の多くのものもエスケープします。 (編集エスケープ文字自体のエスケープが必要です: XML の場合、リテラルが " " としてエスケープされる場合は&" &amp;" です。正規表現の場合、リテラルがエスケープされる場合は C/unix スタイルの " \" です。 " \\")。

構文をネストすると、脱出地獄になります。

簡単な解決策の 1 つは、ユーザーに次のように伝えることです。これは簡単汚い構成エディターなので、特別な「エスケープする必要がない」mamby-pamby は得られません。

  • テキスト領域の横に文字とエスケープをリストします (例: "<" as " &lt")。
  • 検証されない XML の場合は、リストをもう一度表示します。

振り返ってみると、私の前にボビンスが同じ基本的な答えを出していたことがわかります。

于 2009-01-29T18:46:18.873 に答える
1

リッチ テキスト ボックスで html を編集できるTinyMCEのようなものを見ることができます。思い通りに設定できない場合は、インスピレーションとして使用できます。

于 2009-01-28T02:55:17.490 に答える
1

あなたが言うように、通常のシリアライザーはすべてをエスケープする必要があります。

問題はテキスト ブロックです。テキスト ブロックを通過したものはすべて自分で処理する必要があります。

HttpUtility.HtmlEncode() を試すこともできますが、最も簡単な方法は、テキスト ブロックを通過するものをすべて CDATA セクションに入れることだと思います。

もちろん、通常は CDATA の「松葉杖」に頼るのではなく、すべてを適切にエスケープする必要がありますが、組み込みツールを使用してエスケープを行うことも必要です。ユーザーによって「休止状態」の状態で編集されたものについては、CDATA が適していると思います。

この以前の質問も参照してください:
XML のテキスト データをエンコードする最良の方法


更新
別の応答へのコメントに基づいて、コンテンツだけでなくマークアップをユーザーに表示していることに気付きました。XMLパーサーは、まあ、うるさいです。この場合にできる最善のことは、編集された xml を受け入れる 前に整形式であることを確認することだと思います。

おそらく、特定の種類のエラー (リンクされた質問からの不適切なアンパサンドなど) を自動的に修正しようとしますが、.Net xml パーサーから最初の検証エラーの行番号と列番号を取得し、それを使用してユーザーに間違いがどこにあるかを表示します。彼らはあなたに受け入れられるものを与えます。スキーマに対しても検証する場合のボーナス ポイント。

于 2008-10-28T18:42:14.850 に答える
1

すべてのテキストの周りに CDATA を挿入すると、(1) ユーザーが手動でエスケープする必要がなくなり、(2) テキストエリアによって自動的にエスケープ解除されたテキストが正しく読み戻されるようになる別のエスケープ メカニズムが得られます。

 <Configuration>
   <Validator Expression="<![CDATA[  [^<]   ]]>" />
 </Configuration>

:-)

于 2009-02-07T02:20:02.180 に答える
0

この特殊文字 (「<」) は、XML が有効になるように他の文字に置き換える必要があります。XML の特殊文字については、次のリンクを確認してください。

http://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references

また、TextBlock コンテンツをデシリアライザーに送信する前にエンコードしてみてください。

HttpServerUtility utility = new HttpServerUtility();
string encodedText = utility.HtmlEncode(text);
于 2008-10-28T18:31:25.603 に答える
0

これは本当に私の唯一のオプションですか?これは、フレームワークのどこかに解決策があるほど一般的な問題ではありませんか?

private string EscapeAttributes(string configuration)
{
    var lt = @"(?<=\w+\s*=\s*""[^""]*)<(?=[^""]*"")";
    configuration = Regex.Replace(configuration, lt, "&lt;");

    return configuration;
}

(編集: ラウンドトリップの問題を引き起こすため、削除されたアンパサンド置換)

于 2008-10-28T19:41:49.690 に答える