Как, черт возьми, можно редактировать действительный XML на веб-странице?

Мне нужно запустить быстрый и грязный редактор конфигурации. Поток выглядит примерно так:

конфигурация (POCO на сервере) сериализуются в XML.
На данный момент XML хорошо сформирован. Конфигурация отправляется на веб-сервер в XElements.
. На веб-сервере XML (да, ВСЕ ЭТО) выгружается в текстовое поле для редактирования. Пользователь редактирует XML прямо на веб-странице и нажимает «Отправить» .
В ответ я получаю измененный текст конфигурации XML. На данный момент ВСЕ экраны отменены в процессе их отображения на веб-странице. Я пытаюсь загрузить строку в объект XML (XmlElement, XElement и т. д.). КАБУМ.

Проблема в том, что при сериализации строки атрибутов не используются, но при переводе они теряются.

Например, допустим, у меня есть объект с регулярным выражением. Вот конфигурация веб-сервера:

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

Итак, я поместил это в текстовое поле, где это выглядит так для пользователя:

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

Таким образом, пользователь вносит небольшие изменения и отправляет изменения обратно. На веб-сервере строка ответа выглядит так:

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

Итак, пользователь добавил еще одну штуку с валидатором, и теперь ОБА имеют атрибуты с недопустимыми символами. Если я попытаюсь загрузить это в любой XML-объект, это вызовет исключение, потому что <и & недействительны в текстовой строке. Я НЕ МОГУ НЕ МОГУ НЕ МОГУ использовать какую-либо функцию кодирования, поскольку она кодирует всю кровавую вещь:

var result = Server.HttpEncode (editedConfig);

приводит к

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

Это НЕ правильный XML. Если я попытаюсь загрузить это в какой-либо элемент XML, меня ударит падающая наковальня. Я не люблю падающие наковальни.

Итак, вопрос остается ... Единственный способ подготовить эту строку XML к синтаксическому анализу в объект XML - это использовать замену регулярных выражений? Есть ли способ «отключить ограничения» при загрузке? Как это обойти ???


Один последний ответ, а затем wiki-izing это, поскольку я не думаю, что есть действительный ответ.

XML, который я помещаю в текстовое поле, является действительным, экранированным XML. Процесс 1) размещения его в текстовой области 2) отправки его клиенту 3) отображения его клиенту 4) отправки формы, в которой он находится 5) отправки его обратно на сервер и 6) получения значения из формы УДАЛЯЕТ ЛЮБЫЕ И ВСЕ УБЕГАЕТ.

Позвольте мне сказать это еще раз: Я не убегу от НИЧЕГО. Просто отобразите его в браузере!

Над чем поразмыслить: есть ли способ предотвратить это в первую очередь? Есть ли способ взять почти корректный XML и "очистить" его безопасным способом?


За этот вопрос теперь есть награда. Чтобы получить вознаграждение, вы демонстрируете, как редактировать ДЕЙСТВИТЕЛЬНЫЙ XML в окне браузера БЕЗ стороннего инструмента / инструмента с открытым исходным кодом, который не требует от меня использования регулярного выражения для экранирования значений атрибутов вручную, что не требует от пользователей экранирования своих атрибутов, и это не дает сбоев при передаче в оба конца (& amp; amp; amp; etc;)

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
4
0
2 160
8
Перейти к ответу Данный вопрос помечен как решенный

Ответы 8

Ответ принят как подходящий

Эээ… Как вы сериализуете? Обычно сериализатор XML никогда не должен создавать недопустимый XML.

/ EDIT в ответ на ваше обновление: Отображает ли нет недопустимый XML для редактирования вашим пользователем! Вместо этого отобразите правильно экранированный XML в TextBox. Исправлять сломанный XML - это не весело, и я на самом деле не вижу причин не отображать / редактировать XML в допустимой, экранированной форме.

Снова я мог бы спросить: как вы показываете XML в TextBox? Кажется, в какой-то момент вы намеренно отключаете от XML.

/ EDIT в ответ на ваш последний комментарий: Да, очевидно, поскольку он может содержать HTML. Вам нужно правильно экранировать свой XML, прежде чем записывать его на HTML-страницу. Под этим я подразумеваю все XML. Итак, это:

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

становится это:

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

Правильный. Ошибка в вопросе. Fix'd

user1228 28.10.2008 22:17

Поверьте, когда вы берете экранированный xml и помещаете его в ТЕКСТОВУЮ ОБЛАСТЬ для отображения на веб-странице, он отображает экранированные символы как их неэкранированные копии. Я делаю это не специально.

user1228 29.10.2008 14:59

Извините, там была некоторая путаница с textBLOCKS и textAREAS

user1228 29.10.2008 20:51

Этот специальный символ - «<» - нужно было заменить другими символами, чтобы ваш 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);

Да, верно. Вопрос, однако, в том, КАК это сделать. Regex заменить? Или есть более безопасный и надежный способ сделать это?

user1228 28.10.2008 21:37

Я отредактировал свой ответ и добавил образец кода для кодирования текста перед его отправкой в ​​сериализатор.

mohammedn 28.10.2008 21:46

Это ускользает от ВСЕГО, превращая действительный xml (с некоторыми плохими атрибутами) в не-xml. Это не работает.

user1228 28.10.2008 21:55

Подождите: вы тоже показываете пользователям Разметка? Это делает недействительными большую часть моего другого ответа, но, по крайней мере, регулярное выражение в вопросе, на который я ссылался, все еще может вам помочь.

Joel Coehoorn 28.10.2008 21:59

Как вы говорите, обычный сериализатор должен избавить вас от всего.

Таким образом, проблема заключается в текстовом блоке: вам нужно самостоятельно обрабатывать все, что проходит через текстовый блок.

Вы можете попробовать HttpUtility.HtmlEncode (), но я думаю, что самый простой способ - просто заключить все, что вы передаете через текстовый блок, в раздел CDATA.

Обычно, конечно, я бы хотел, чтобы все было правильно экранировано, вместо того, чтобы полагаться на «костыль» CDATA, но я также хотел бы использовать встроенные инструменты для экранирования. Я думаю, что для чего-то, что редактируется пользователем в "спящем" состоянии, лучше всего подойдет CDATA.

Также см. Предыдущий вопрос:
Лучший способ кодировать текстовые данные для XML


Обновлять
Основываясь на комментарии к другому ответу, я понял, что вы показываете пользователям разметку, а не только содержимое. Xml-парсеры, ну, разборчивы. Я думаю, что лучшее, что вы могли бы сделать в этом случае, - это проверить правильность формата до, принимающего отредактированный xml.

Возможно, попробуйте автоматически исправить определенные виды ошибок (например, плохие амперсанды из моего связанного вопроса), но затем получите номер строки и номер столбца первой ошибки проверки из синтаксического анализатора .Net xml и используйте это, чтобы показать пользователям, где их ошибка, пока они дают вам что-то приемлемое. Бонусные баллы, если вы также проверяете схему.

Да, я показываю необработанную, голую разметку sexxay в TextBlock. Как я уже сказал, быстрый и грязный редактор конфигурации. Конфигурация = xml, редактор = TextBlock + xml

user1228 28.10.2008 22:06

Я бы хотел, чтобы пользователи не заставляли себя убегать. Он выходит без экранирования, что означает, что они должны прополоть СОТНИ строк XML, чтобы исправить то, что сломано, ДО того, как они изменят конфигурацию. КОШМАРНЫЙ СОН.

user1228 28.10.2008 22:08

Идея здесь в том, чтобы вы могли исправить определенные типы распространенных ошибок для них и, по крайней мере, показать им, где проблема для ошибок, если вы не можете ее исправить.

Joel Coehoorn 28.10.2008 22:20

Важно то, что независимо от того, что вы не должны принимать пользовательский ввод, который сломает объект, вы не сможете учесть каждую возможную ошибку, которую кто-то может сделать в документе. Так что вам все равно нужно будет реализовать некоторую логику проверки.

Joel Coehoorn 28.10.2008 22:23

Быстро и грязно; если они сломают его, он сломается. Я не против. Но просто АКТ отображения его на веб-странице нарушает его. Я хочу как минимум предотвратить это. Регулярное выражение?

user1228 28.10.2008 22:27

Это выражение найдет любой амперсанд, который не является частью объекта, что противоречит правилам в Xml: & (?! [A-zA-Z] {2,6}; | # [0-9] {2, 4};)

Joel Coehoorn 28.10.2008 22:29

Я хотел бы хотя бы предупреждать пользователю, что представленные значения недействительны: дать им выбор, попытаться исправить или отправить в любом случае. Но я вижу, где у вас более серьезная проблема: теперь нет разницы между символом «меньше чем», который используется для тега, и символом, который используется для содержимого.

Joel Coehoorn 28.10.2008 22:32

Неужели это единственный вариант? Разве это не достаточно распространенная проблема, чтобы найти решение где-нибудь в рамках?

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

    return configuration;
}

(править: удаленная замена амперсанда, поскольку это вызывает проблемы с возвратом)

Я знаю. Это страшно. Вот почему я удивлен, что нет ничего, что можно было бы использовать в качестве альтернативы.

user1228 28.10.2008 23:01

Конечно, когда вы помещаете ссылки на объекты внутри текстового поля, они выходят без экранирования. Текстовые области - это не волшебство, вам нужно & убежать; все, что вы в них вкладываете, как и любой другой элемент. Браузеры могут отображать использовать необработанный знак «<» в текстовой области, но только потому, что они пытаются исправить ваши ошибки.

Поэтому, если вы помещаете редактируемый 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: Ну, а какая проблема остается? Это проблема сериализации. Все, что остается, - это разобрать его обратно, и для этого вы должны предположить, что пользователь может создать правильно сформированный XML.

Попытка проанализировать неверно сформированный XML, чтобы допустить ошибки, такие как наличие "<" или "&" без экранирования в значении атрибута, является потерей, полностью противоречащей тому, как должен работать XML. Если вы не можете доверять своим пользователям писать правильно сформированный XML, дайте им более простой интерфейс, отличный от XML, например простой список строк регулярного выражения, разделенных новой строкой.

Вы можете взглянуть на что-то вроде TinyMCE, которое позволяет редактировать html в поле форматированного текста. Если вы не можете настроить его так, чтобы он делал именно то, что вы хотите, вы можете использовать его как источник вдохновения.

Рассмотрены, отвергнуты. Кроме того, «продемонстрируйте, как редактировать ДЕЙСТВИТЕЛЬНЫЙ XML в окне браузера БЕЗ сторонних инструментов / инструментов с открытым исходным кодом». в любом случае спасибо за ответ.

user1228 28.01.2009 18:14

Примечание: 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>

Так что, возможно, одно (нежизнеспособное?) Решение для ваших пользователей - использовать firefox.


Похоже, в вашем вопросе были обнаружены две части:

1 XML, который вы показываете, не экранируется.

Например, «&lt;» не экранируется как «<». Но поскольку «<» также не экранируется как «<», информация теряется, и вы не можете ее вернуть.

Одно из решений - экранировать все символы «&», чтобы «&lt;» превратилось в «&amp;lt;». Затем текстовое поле не будет экранировать его как «&lt;». Когда вы перечитаете его, он будет таким, каким был изначально. (Я предполагаю, что текстовое поле действительно меняет строку, но firefox не работает так, как вы сообщаете, поэтому я не могу это проверить)

Другое решение (уже упоминавшееся, я думаю) - создать / купить / заимствовать пользовательскую текстовую область (неплохо, если просто, но есть все клавиши редактирования, ctrl-C, ctrl-shift-left и так далее).

2 Вы бы хотели, чтобы пользователи не беспокоились о побеге.

Ты в аду побега:

Замена регулярного выражения будет в основном работать ... но как вы можете надежно определить конечную цитату ("), когда пользователь может (законно, в рамках указанных вами условий) ввести:

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

Глядя на это с точки зрения синтаксиса регулярного выражения, он также не может сказать, является ли последний "частью регулярного выражения или его концом. Синтаксис регулярных выражений обычно решает эту проблему с помощью явного терминатора, например:

/[^"<]/

Если пользователи использовали этот синтаксис (с терминатором), и вы написали для него синтаксический анализатор, то вы могли бы определить, когда регулярное выражение закончилось, и, следовательно, следующий "символ не является частью регулярного выражения, а является частью XML, и следовательно, какие части нужно убрать. Я не говорю, что вы должны это делать! Я говорю, что это теоретически возможно. Это довольно далеко не быстро и грязно.

BTW: такая же проблема возникает для текста внутри элемента. Следующее является допустимым в рамках указанных вами условий, но имеет те же проблемы с синтаксическим анализом:

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

Основное правило в синтаксисе, которое позволяет использовать «любой текст», состоит в том, что ограничитель должен должен быть экранирован (например, «или <), чтобы можно было распознать конец. Большая часть синтаксиса также экранирует множество других вещей для удобства / неудобства. (РЕДАКТИРОВАТЬ ему потребуется экранирование для самого escape-символа: для XML это "&", который, когда литерал экранирован как "&amp;", для регулярного выражения это "\" в стиле C / unix, который, когда литерал экранирован как "\\").

Вложите синтаксисы, и вы в аду побега.

Одно простое решение для вас - сказать вашим пользователям: это редактор конфигурации быстро и грязный, так что вы не получите никаких причуд "не нужно убегать" mamby-pamby:

  • Далее перечислите персонажей и побеги в текстовую область, например: "<" как «&lt».
  • Для XML, который не будет подтвердите, покажите им список снова.

Оглядываясь назад, я вижу, что бобинс дал тот же базовый ответ до меня.

Довольно много. Мне все еще остается экранировать ввод пользователя. Проблема, с которой я столкнулся, заключается в том, что я не могу использовать правильные синтаксические анализаторы / объекты xml и «помогать» им, когда они сталкиваются с недопустимым xml; это предложение "все или ничего". Мне нужно заменить регулярное выражение, чтобы заставить его работать; Я хочу знать, есть ли другие способы.

user1228 30.01.2009 17:18

Вы должны каким-то образом разбираться. Заменить регулярное выражение проще всего, но я надеюсь, что я показал, что вам нужно определить текстовое содержимое таким образом, чтобы вы могли определить, где заканчивается текст (поскольку вы больше не можете полагаться на "и <синтаксиса XML для выполнения это для вас), и это трудно сделать правильно с регулярным выражением.

13ren 30.01.2009 22:27

Вставка CDATA вокруг всего текста даст вам еще один механизм экранирования, который (1) избавит пользователей от экранирования вручную и (2) позволит правильно прочитать текст, который был автоматически экранирован текстовым полем.

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

:-)

Другие вопросы по теме