Заменить & на & в C # - PullRequest
       23

Заменить & на & в C #

5 голосов
/ 30 сентября 2010

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

Я создаю XML-файл для программы, которая очень требовательна к синтаксису.К сожалению, я делаю XML-файл с нуля.Это значит, что я помещаю каждую строку по отдельности (много файлов. WriteLine (String)).

Я знаю, что это ужасно, но это единственный способ заставить логику работать.1006 * ИНАЧЕ.У меня есть несколько строк с '&' в них.

if (value.Contains("&"))
   {
      value.Replace("&", "&");
   }

Кажется, не работает.Значение .Contains (), кажется, видит это, но замена не работает.Я использую C # .Net 2.0 sp2.VS 2005.

Пожалуйста, помогите мне здесь .. Это была длинная неделя ..

Ответы [ 12 ]

30 голосов
/ 30 сентября 2010

Если вы действительно хотите пойти по этому пути, вы должны присвоить результат Replace (метод возвращает новую строку, потому что строки неизменны) обратно в переменную:

value = value.Replace("&", "&");

Я быпредложите переосмыслить способ написания XML.Если вы переключитесь на использование XmlTextWriter, он будет обрабатывать всю кодировку для вас (не только амперсанд, но и все другие символы, которые также должны быть закодированы):

using(var writer = new XmlTextWriter(@"C:\MyXmlFile.xml", null))
{
    writer.WriteStartElement("someString");
    writer.WriteText("This is < a > string & everything will get encoded");
    writer.WriteEndElement();
}

должен производить:

<someString>This is &lt; a &gt; string &amp; 
    everything will get encoded</someString>
8 голосов
/ 30 сентября 2010

Вы должны действительно использовать что-то вроде Linq to XML (XDocument и т. Д.), Чтобы решить это. Я на 100% уверен, что вы можете сделать это без всех ваших WriteLine ´s;) Покажите нам свою логику?

В противном случае вы можете использовать это, что будет пуленепробиваемым (в отличие от .Replace("&")):

var value = "hej&hej<some>";
value = new System.Xml.Linq.XText(value).ToString(); //hej&amp;hej&lt;some&gt;

Это также позаботится о <, от которого вы также должны Бежать:)

Обновление: Я рассмотрел код для XText.ToString(), и внутри он создает XmlWriter + StringWriter и использует XNode.WriteTo. Это может быть излишним для данного приложения, поэтому, если нужно преобразовать много строк, XText.WriteTo будет лучше. Альтернатива, которая должна быть быстрой и надежной, это System.Web.HttpUtility.HtmlEncode.

Обновление 2: Я нашел это System.Security.SecurityElement.Escape(xml), которое может быть самым быстрым и обеспечивает максимальную совместимость (поддерживается начиная с .Net 1.0 и не требует ссылки System.Web).

3 голосов
/ 06 октября 2011

Вы можете использовать Regex для замены символа "&" только в значениях узла:

пример ввода данных (строка)

<select>
 <option id="11">Gigamaster&Minimaster</option>
 <option id="12">Black & White</option>
 <option id="13">Other</option>
</select>

Замена на Regex

 Regex rgx = new Regex(">(?<prefix>.*)&(?<sufix>.*)<");
 data = rgx.Replace(data, ">${prefix}&amp;${sufix}<");

 XmlDocument xmlDoc = new XmlDocument();
 xmlDoc.LoadXml(data);

данные результата

<select>
 <option id="11">Gigamaster&amp;MiniMaster</option>
 <option id="12">Black &amp; White</option>
 <option id="13">Other</option>
</select>
3 голосов
/ 30 сентября 2010

вы также можете использовать класс HttpUtility.HtmlEncode в пространстве имен System.Web вместо того, чтобы выполнять замену самостоятельно. здесь вы идете: http://msdn.microsoft.com/en-us/library/73z22y6h.aspx

2 голосов
/ 22 января 2016

Я Очевидно очень поздно, но правильный ответ:

System.Text.RegularExpressions.Regex.Replace(input, "&(?!amp;)", "&amp;");

Надеюсь, это кому-нибудь поможет!

1 голос
/ 23 января 2014

Я создал следующую функцию для кодирования & и 'без путаницы с уже закодированными & или & apos; или "

    public static string encodeSelectXMLCharacters(string xmlString)
    {
        string returnValue = Regex.Replace(xmlString, "&(?!quot;|apos;|amp;|lt;|gt;#x?.*?;)|'",
            delegate(Match m)
            {
                string encodedValue;
                switch (m.Value)
                {
                    case "&":
                        encodedValue = "&amp;";
                        break;
                    case "'":
                        encodedValue = "&apos;";
                        break;
                    default:
                        encodedValue = m.Value;
                        break;
                }

                return encodedValue;
            });
        return returnValue;
    }
1 голос
/ 30 сентября 2010

Строки неизменны. Вам необходимо написать:

value = value.Replace("&", "&amp;");

Обратите внимание, что если вы сделаете это, и ваша строка будет содержать "&amp;", она будет изменена на "&amp;amp;".

1 голос
/ 30 сентября 2010

Вы можете попробовать:

value = value.Replace("&", "&amp;");
0 голосов
/ 27 марта 2019

Я вполне уверен, что это сработает, если вы «охватите» свою ценность с помощью CDATA, поэтому результат будет примерно таким:

<ampersandData><![CDATA[value with ampersands like &hellip;]]></ampersandData>

Надеюсь, это поможет.

0 голосов
/ 27 марта 2019

Очень поздно здесь, но я хочу поделиться своим решением, которое обрабатывает случаи, когда у вас есть и & (неверный xml) и & (действительный xml) в документе в дополнение к другим символам xml.

Это решение предназначено только для случаев, когда вы не можете управлять генерацией XML, как правило, потому что это происходит из какого-то внешнего источника. Если вы управляете генерацией xml, пожалуйста, используйте XmlTextWriter, как предложено @Justin Niessner

Это также довольно быстро и обрабатывает все различные сущности / ссылки на символы XML

Предопределенные символьные объекты:

& quot;

& amp;

'

& lt;

& gt;

Числовые символьные объекты / ссылки:

& #nnnn;

& #xhhhh;

PS! Пробел после & не должен быть включен в сущности / ссылки, я просто добавил его здесь, чтобы избежать его кодирования при визуализации страницы

Код

    public static string CleanXml(string text)
    {
        int length = text.Length;
        StringBuilder stringBuilder = new StringBuilder(length);

        for (int i = 0; i < length; ++i)
        {
            if (text[i] == '&')
            {
                var remaining = Math.Abs(length - i + 1);
                var subStrLength = Math.Min(remaining, 12);
                var subStr = text.Substring(i, subStrLength);
                var firstIndexOfSemiColon = subStr.IndexOf(';');
                if (firstIndexOfSemiColon > -1)
                    subStr = subStr.Substring(0, firstIndexOfSemiColon + 1);
                var matches = Regex.Matches(subStr, "&(?!quot;|apos;|amp;|lt;|gt;|#x?.*?;)|'");
                if (matches.Count > 0)
                    stringBuilder.Append("&amp;");
                else
                    stringBuilder.Append("&");
            }
            else if (XmlConvert.IsXmlChar(text[i]))
            {
                stringBuilder.Append(text[i]);
            }
            else if (i + 1 < length && XmlConvert.IsXmlSurrogatePair(text[i + 1], text[i]))
            {
                stringBuilder.Append(text[i]);
                stringBuilder.Append(text[i + 1]);
                ++i;
            }
        }

        return stringBuilder.ToString();
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...