Frage

Ich muss einen schnellen und schmutzigen Konfigurationseditor in Betrieb nehmen. Der Fluss geht ungefähr so:

Die Konfiguration (POCOS auf dem Server) werden nach XML serialisiert.
Der XML ist an dieser Stelle gut geformt. Die Konfiguration wird in Xelements an den Webserver gesendet.
Auf dem Webserver wird der XML (ja, alles) zur Bearbeitung in einen Textbereich abgeladen.
Der Benutzer bearbeitet den XML direkt auf der Webseite und klickt auf.
In der Antwort rufe ich den veränderten Text der XML -Konfiguration ab. Zu diesem Zeitpunkt wurden alle Flucht durch den Prozess der Anzeige in einer Webseite zurückgekehrt.
Ich versuche, die Zeichenfolge in ein XML -Objekt zu laden (xmlelement, xelement, was auch immer). Kaboom.

Das Problem ist, dass die Serialisierung zu Attributzeichenfolgen entgeht, dies geht jedoch in der Übersetzung auf dem Weg verloren.

Nehmen wir zum Beispiel an, ich habe ein Objekt mit einer Regex. Hier ist die Konfiguration, die zum Webserver kommt:

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

Also habe ich das in einen Textbereich gesteckt, in dem es dem Benutzer so aussieht:

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

Der Benutzer führt also eine leichte Änderung vor und reicht die Änderungen zurück. Auf dem Webserver sieht die Antwortzeichenfolge aus wie:

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

Der Benutzer fügte also ein weiteres Validator -Ding hinzu, und jetzt haben beide Attribute mit illegalen Zeichen. Wenn ich versuche, dies in ein XML -Objekt zu laden, wird eine Ausnahme ausgelegt, da <und in einer Textzeichenfolge nicht gültig ist. Ich kann keine Codierungsfunktion nicht verwenden, da sie das gesamte blutige Ding codiert:

var result = server.httpencode (editedConfig);

führt in

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

Dies ist kein gültiges XML. Wenn ich versuche, dies in ein XML -Element jeglicher Art zu laden, werde ich von einem fallenden Amboss getroffen. Ich mag es nicht, Ambossen zu fallen.

Die Frage bleibt also ... ist der einzige Weg, wie ich diese String -XML -Analyse in ein XML -Objekt vorbereiten kann, indem Regex ersetzt wird? Gibt es eine Möglichkeit, die Einschränkungen auszuschalten, wenn ich lade? Wie kommst du um das ???


Eine letzte Antwort und dann wiki-auf diese, da ich nicht glaube, dass es eine gültige Antwort gibt.

Der XML, den ich in der TextArea platziert, ist gültig, entkommen XML. Der Vorgang von 1) Einlegen in den Textbereich 2) Senden Sie ihn an den Client 3) Anzeigen des Clients 4) Senden des Formulars 5) Senden Sie ihn an den Server zurück und 6) Abzweigung des Werts aus dem Formular entfernt Alle und alle entkommen.

Lassen Sie mich das noch einmal sagen: Ich bin nichts uneswesst. Wenn Sie es einfach im Browser anzeigen, tun Sie dies!

Dinge zu überlegen: Gibt es eine Möglichkeit, zu verhindern, dass diese Unauskämpfung überhaupt passiert? Gibt es eine Möglichkeit, XML fast valid zu nehmen und auf sichere Weise "zu reinigen"?


Diese Frage hat nun ein Kopfgeld. Um das Kopfgeld zu sammeln, zeigen Sie, wie Sie gültige XML in einem Browserfenster ohne ein Drittanbieter-/Open -Source -Tool bearbeiten, bei dem ich nicht regex verwendet werden muss, um Attributwerte manuell zu entkommen. Damit sind Benutzer nicht erforderlich, um ihren Attributen zu entkommen. Und das scheitert nicht, wenn Roundtrips (& amp; Amp; Amp; usw;)

War es hilfreich?

Lösung

Ähm…Wie Serialisieren Sie? Normalerweise sollte der XML -Serializer niemals ungültige XML erzeugen.

/Bearbeiten Sie als Antwort auf Ihr Update: TO nicht Zeigen Sie Ihrem Benutzer ungültige XML an! Zeigen Sie stattdessen den ordnungsgemäß entkommenen XML in der Textbox an. Das Reparieren von zerbrochenem XML macht keinen Spaß und ich sehe tatsächlich keinen Grund, das XML in einem gültigen, entkommenen Formular nicht anzuzeigen/zu bearbeiten.

Wieder konnte ich fragen: wie Zeigen Sie die XML im Textfeld an? Sie scheinen das XML irgendwann absichtlich zu entzünden.

/Bearbeiten Sie als Antwort auf Ihren neuesten Kommentar: Nun ja, natürlich, da es HTML enthalten kann. Sie müssen Ihrem XML ordnungsgemäß entkommen, bevor Sie es in eine HTML -Seite schreiben. Damit meine ich das ganz Xml. Also das:

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

wird dies:

&lt;foo mean-attribute="&amp;&lt;"&gt;

Andere Tipps

Wenn Sie Referenzen in einem Textbereich nicht enttäuschen, kommen sie natürlich unabgeordnet heraus. Textbereich sind keine Magie, Sie müssen und entkommen; Alles, was Sie genau wie jedes andere Element eingeben. Browser könnten Anzeige Ein rohes '<' in einem Textbereich, aber nur, weil sie versuchen, Ihre Fehler aufzuräumen.

Wenn Sie also einen textbereich bearbeitbaren XML einfügen, müssen Sie dem Attributwert einmal entkommen, um ihn gültig zu machen. Die letzte Quelle, die Sie auf der Seite erscheinen möchten, wäre:

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

Die Frage basiert auf einem Missverständnis des Inhaltsmodells des Textbereichselements - ein Validator hätte das Problem sofort aufgenommen.

ETA Re Kommentar: Nun, welches Problem bleibt bestehen? Das ist das Problem auf der Serialisierungsseite. Alles, was übrig bleibt, ist es wieder an Parsen, und dafür müssen Sie annehmen, dass der Benutzer gut geformte XML erstellen kann.

Der Versuch, nicht ausgebildete XML zu analysieren, um Fehler wie "<" oder "&" in einem Attributwert nicht zu haben, ist ein Verlust, völlig dagegen, wie XML funktionieren soll. Wenn Sie Ihren Benutzern nicht vertrauen können, um gut geformtes XML zu schreiben, geben Sie ihnen eine einfachere Nicht-XML-Oberfläche, z.

Wie Sie sagen, sollte der normale Serializer alles für Sie entkommen.

Das Problem ist also der Textblock: Sie müssen alles bewältigen, was selbst durch den Textblock geleitet wird.

Sie könnten httputility.htmlencode () ausprobieren, aber ich denke, die einfachste Methode besteht darin, nur alles zu verschleppen, was Sie den Textblock in einem CDATA -Abschnitt durchgeben.

Normalerweise möchte ich natürlich, dass alles richtig entkommen ist, anstatt mich auf die CDATA-Krücke zu verlassen, aber ich möchte auch die eingebauten Werkzeuge verwenden, um die Flucht durchzuführen. Für etwas, das von einem Benutzer in seinem "Hibernated" -Zustand bearbeitet wird, denke ich, dass CDATA der richtige Weg sein könnte.

Siehe auch diese frühere Frage:
Beste Möglichkeit, Textdaten für XML zu codieren


Aktualisieren
Basierend auf einem Kommentar zu einer anderen Antwort habe ich festgestellt, dass Sie den Benutzern das Markup zeigen, nicht nur den Inhalt. XML -Parser sind wählerisch. Ich denke Vor Akzeptieren des bearbeiteten XML.

Versuchen Sie vielleicht, bestimmte Arten von Fehlern automatisch zu korrigieren (wie schlechte Verstärker von meiner verknüpften Frage), aber dann die Zeilennummer und Spaltennummer des ersten Validierungsfehler Sie geben Ihnen etwas Akzeptable. Bonuspunkte, wenn Sie auch gegen ein Schema bestätigen.

Sie könnten sich etwas ansehen wie Tinymce, damit Sie HTML in einem reichen Textfeld bearbeiten können. Wenn Sie es nicht so konfigurieren können, dass Sie genau das tun, was Sie wollen, können Sie es als Inspiration verwenden.

HINWEIS: Firefox (in meinem Test) entsteht in Textbereichen, wie Sie beschreiben, nicht. Insbesondere dieser Code:

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

Wird dem Benutzer alarmiert und angezeigt unverändert, wie:

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

Vielleicht ist eine (nicht nachtbare?) Lösung, damit Ihre Benutzer Firefox verwenden können.


Es scheint, dass zwei Teile Ihrer Frage offenbart wurden:

1 XML, das Sie anzeigen, wird unbegabt.

Zum Beispiel, "&lt;"ist als" <"unablegt. Aber da" <"auch als" <"nicht ausgebildet ist, sind Informationen verloren und Sie können es nicht zurückbekommen.

Eine Lösung ist es, allen "zu entkommen"&"Charaktere, so dass"&lt;" wird "&amp;lt;". Dies wird dann von der Textea als" unabgeordnet sein "&lt;". Wenn Sie es zurücklesen, wird es so sein, wie es überhaupt war. (Ich gehe davon aus, dass die textarea tatsächlich die Zeichenfolge ändert, aber Firefox verhält sich nicht so, wie Sie berichten, also kann ich das nicht überprüfen.

Eine andere Lösung (bereits erwähnt, denke ich) besteht darin, einen benutzerdefinierten Textbereich zu bauen/zu kaufen/auszuleihen (nicht schlecht, wenn es einfach ist, aber es gibt alle Bearbeitungsschlüssel, Strg-C, Strg-Shift-Links usw.).

2 Sie möchten, dass Benutzer sich nicht die Mühe machen müssen, zu entkommen.

Du bist in Escape-Hell:

Ein Regex -Ersatz funktioniert hauptsächlich ... aber wie können Sie das Endangebot zuverlässig erkennen ("), wenn der Benutzer (legitim, innerhalb der von Ihnen angegebenen Bedingungen) eingeben könnte:

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

Wenn man es aus der Sicht der Regex -Syntax betrachtet, kann es auch nicht erkennen, ob das Finale "Teil des Regex ist, oder das Ende davon. Die Regex -Syntax löst dieses Problem normalerweise mit einem expliziten Terminator, z. B.

/[^"<]/

Wenn Benutzer diese Syntax (mit dem Terminator) verwendeten und Sie einen Parser dafür geschrieben haben, können Sie feststellen, wann der Regex beendet ist, und deshalb ist der nächste "Charakter nicht Teil des Regex, sondern Teil des XML und Teil Deshalb müssen welche Teile entkommen werden. Ich sage nicht, dass Sie dies tun sollten! Ich sage, es ist theoretisch möglich. Es ist ziemlich weit von schnell und schmutzig.

Übrigens: Das gleiche Problem tritt für Text innerhalb eines Elements auf. Das Folgende ist legitim, innerhalb der Bedingungen, die Sie angegeben haben, hat jedoch die gleichen Parsingprobleme:

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

Die grundlegende Regel in einer Syntax, die "jeden Text" ermöglicht, ist, dass der Trennzeichen muss entkommen sein, (zB "oder <), damit das Ende erkannt werden kann.BEARBEITEN Es muss eine Flucht für den Fluchtcharakter selbst benötigen: für XML ist es "&", was, wenn buchstäblich als entkommen wird"&amp;"Für Regex ist es das C/Unix-Stil"\", was, wenn buchstäblich als entkommen wird"\\").

NEST-Syntaxes, und Sie sind in Escape-Hell.

Eine einfache Lösung für Sie besteht darin, Ihren Benutzern zu sagen: Dies ist a schnell und schmutzig Konfigurationseditor, sodass Sie Mamby-Pamby nicht "nicht entkommen" erhalten:

  • Listen Sie die Zeichen und entkommen neben dem Textbereich auf, z. B. "<" as "&lt".
  • Für XML, das nicht bestätigt wird, zeigen Sie ihnen die Liste erneut.

Rückblickend sehe ich Bobel gab die gleiche grundlegende Antwort vor mir.

Wenn Sie CDATA in den gesamten Text einfügen, können Sie einen weiteren Fluchtmechanismus geben, der (1) den Benutzern vor dem manuellen Entkommen bewahren würde, und (2) den Text, der automatisch von der textarea ordnungsgemäß zurückgelesen wurde, automatisch unabgeordnet wurde.

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

:-)

Dieses spezielle Charakter - "<" - hätte durch andere Zeichen ersetzt werden sollen, damit Ihr XML gültig ist. Überprüfen Sie diesen Link für XML -Sonderzeichen:

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

Versuchen Sie auch, Ihren Textblockinhalt zu codieren, bevor Sie ihn an den Deserializer senden:

HttpServerUtility utility = new HttpServerUtility();
string encodedText = utility.HtmlEncode(text);

Ist das wirklich meine einzige Option? Ist dies nicht ein häufig genuges Problem, dass es irgendwo im Rahmen eine Lösung hat?

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

    return configuration;
}

(Bearbeiten: Löschter Verstärker und Austausch, da dies Probleme verursacht, Rundweg)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top