парсинг XML с амперсандом

У меня есть строка, которая содержит XML, я просто хочу проанализировать его в Xelement, но он имеет амперсанд. У меня все еще есть проблема parseing это с HtmlDecode. Какие-либо предложения?

string test = " <MyXML><SubXML><XmlEntry Element="test" value="wow&" /></SubXML></MyXML>"; 

XElement.Parse(HttpUtility.HtmlDecode(test));

Я также добавил эти методы для замены тех символов, но я все еще получаю XMLException.

string encodedXml = test.Replace("&", "&amp;").Replace("<", "&lt;").Replace(">", "&gt;").Replace("\"", "&quot;").Replace("'", "&apos;");
XElement myXML = XElement.Parse(encodedXml);

t или Даже попробованный это этим:

string newContent=  SecurityElement.Escape(test);
XElement myXML = XElement.Parse(newContent);
16
задан sao 23 September 2019 в 12:47
поделиться

6 ответов

В идеале XML экранируется правильно до того, как ваш код использует его. Если это вне вашего контроля, вы можете написать регулярное выражение. Не используйте метод String.Replace, если вы не уверены, что значения не содержат других экранированных элементов.

Например, "wow & amp;". Replace ("&", "& amp;") приводит к wow & amp; , что явно нежелательно.

Regex.Replace может дать вам больше контроля, чтобы избежать этого сценария, и может быть написано только для соответствия символам "&", которые не являются частью другие символы, такие как & lt; , что-то вроде:

string result = Regex.Replace(test, "&(?!(amp|apos|quot|lt|gt);)", "&amp;");

Вышеупомянутое работает, но, по общему признанию, оно не охватывает множество других символов, начинающихся с амперсанда, таких как & nbsp; и список может расти.

Более гибкий подход заключался бы в декодировании содержимого атрибута значения, а затем его перекодировании. Если у вас есть value = "& wow & amp;" , процесс декодирования вернет "& wow &" , затем при повторном кодировании он вернет "& amp; wow & amp;" , что желательно. Для этого вы можете использовать следующее:

string result = Regex.Replace(test, @"value=\""(.*?)\""", m => "value=\"" +
    HttpUtility.HtmlEncode(HttpUtility.HtmlDecode(m.Groups[1].Value)) +
    "\"");
var doc = XElement.Parse(result);

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


РЕДАКТИРОВАТЬ: обновленное решение, которое должно обрабатывать содержимое между тегами, а также все, что находится между двойными кавычками. Обязательно проверьте это тщательно. Попытка манипулировать тегами XML / HTML с помощью регулярного выражения нецелесообразна, поскольку может быть подвержена ошибкам и слишком сложна. Ваш случай в чем-то особенный, так как вам нужно сначала продезинфицировать его, чтобы использовать.
string pattern = "(?<start>>)(?<content>.+?(?<!>))(?<end><)|(?<start>\")(?<content>.+?)(?<end>\")";
string result = Regex.Replace(test, pattern, m =>
            m.Groups["start"].Value +
            HttpUtility.HtmlEncode(HttpUtility.HtmlDecode(m.Groups["content"].Value)) +
            m.Groups["end"].Value);
var doc = XElement.Parse(result);
20
ответ дан 30 November 2019 в 16:36
поделиться

HtmlEncode не поможет, он, вероятно, создаст еще больше амперсандов (например, «может стать», которое является ссылкой на сущность Xml, а именно:

&amp;   & 
&apos;  ' 
&quot;  " 
&lt;    < 
&gt;    > 

Но возможно, вы получите такие вещи, как & nbsp, что хорошо в html, но не в Xml. Поэтому, как все говорили, сначала исправьте xml, убедившись, что любой символ, который является НЕ ЧАСТЬ ФАКТИЧЕСКОЙ РАЗМЕТКИ ВАШЕГО XML (то есть что-нибудь ВНУТРИ вашего xml в виде переменной или текста ), и то, что встречается в списке ссылок на сущности, переводится в их соответствующую сущность (поэтому <будет <). Если текст, содержащий недопустимый символ - это текст внутри узла xml, вы можете пойти по простому пути и окружить текст элементом CDATA, однако для атрибутов это не сработает.

3
ответ дан 30 November 2019 в 16:36
поделиться

Ваша строка не содержит допустимого XML, вот в чем проблема. Вам нужно изменить вашу строку на:

<MyXML><SubXML><XmlEntry Element="test" value="wow&amp;" /></SubXML></MyXML>"
14
ответ дан 30 November 2019 в 16:36
поделиться

Амперсант делает XML недействительным . Это не может быть исправлено таблицей стилей, поэтому вам нужно написать код с помощью другого инструмента или кода на VB / C # / PHP / Delphi / Lisp / Etc. чтобы удалить его или перевести на & amp;.

1
ответ дан 30 November 2019 в 16:36
поделиться

Если ваша строка не является допустимым XML, она не будет проанализирована. Если он сам по себе содержит амперсанд, это недействительный XML. В отличие от HTML, XML очень строг.

0
ответ дан 30 November 2019 в 16:36
поделиться

Вы должны «кодировать», а не декодировать. Но вызов HttpUtility.HtmlEncode вам не поможет, так как он также закодирует ваши символы '<' и '>', и ваша строка больше не будет XML.

Я думаю, что в этом случае лучшим решением будет замена '&' с '& amp;' (без пробела)

0
ответ дан 30 November 2019 в 16:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: