Замените символы в строке, которые не де-сериализованы в C # [дубликат]

Это зависит от числа строк, если в сотнях создается сценарий столбца обновления и запускается, но если он находится в большом объеме, импортируйте этот файл в новую таблицу и обновите таблицу с помощью соединения, и затем отпустите таблицу

60
задан Igor Kustov 5 January 2017 в 01:31
поделиться

6 ответов

Как способ удаления недопустимых символов XML, я предлагаю вам использовать метод XmlConvert.IsXmlChar . Он был добавлен с .NET Framework 4 и представлен также в Silverlight. Вот небольшой пример:

void Main() {
    string content = "\v\f\0";
    Console.WriteLine(IsValidXmlString(content)); // False

    content = RemoveInvalidXmlChars(content);
    Console.WriteLine(IsValidXmlString(content)); // True
}

static string RemoveInvalidXmlChars(string text) {
    var validXmlChars = text.Where(ch => XmlConvert.IsXmlChar(ch)).ToArray();
    return new string(validXmlChars);
}

static bool IsValidXmlString(string text) {
    try {
        XmlConvert.VerifyXmlChars(text);
        return true;
    } catch {
        return false;
    }
}

И как способ избежать недопустимых символов XML, я предлагаю вам использовать метод XmlConvert.EncodeName . Вот небольшой пример:

void Main() {
    const string content = "\v\f\0";
    Console.WriteLine(IsValidXmlString(content)); // False

    string encoded = XmlConvert.EncodeName(content);
    Console.WriteLine(IsValidXmlString(encoded)); // True

    string decoded = XmlConvert.DecodeName(encoded);
    Console.WriteLine(content == decoded); // True
}

static bool IsValidXmlString(string text) {
    try {
        XmlConvert.VerifyXmlChars(text);
        return true;
    } catch {
        return false;
    }
}

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

88
ответ дан Igor Kustov 15 August 2018 в 20:27
поделиться
// Replace invalid characters with empty strings.
   Regex.Replace(inputString, @"[^\w\.@-]", ""); 

Шаблон регулярного выражения [^ \ w. @ -] соответствует любому символу, который не является символом слова, периодом, символом @ или дефисом. Символом слова является любая буква, десятичная цифра или знак пунктуации, такой как символ подчеркивания. Любой символ, соответствующий этому шаблону, заменяется на String.Empty, который является строкой, определяемой шаблоном замены. Чтобы добавить дополнительные символы в пользовательский ввод, добавьте эти символы в класс символов в шаблоне регулярных выражений. Например, шаблон регулярного выражения [^ \ w. @ - \%] также допускает символ процента и обратную косую черту во входной строке.

Regex.Replace(inputString, @"[!@#$%_]", "");

См. Также:

Удаление недопустимых символов из тега имени XML - RegEx C #

Ниже приведена функция для удаления символов из указанной XML-строки:

using System;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;

namespace XMLUtils
{
    class Standards
    {
        /// <summary>
        /// Strips non-printable ascii characters 
        /// Refer to http://www.w3.org/TR/xml11/#charsets for XML 1.1
        /// Refer to http://www.w3.org/TR/2006/REC-xml-20060816/#charsets for XML 1.0
        /// </summary>
        /// <param name="content">contents</param>
        /// <param name="XMLVersion">XML Specification to use. Can be 1.0 or 1.1</param>
        private void StripIllegalXMLChars(string tmpContents, string XMLVersion)
        {    
            string pattern = String.Empty;
            switch (XMLVersion)
            {
                case "1.0":
                    pattern = @"#x((10?|[2-F])FFF[EF]|FDD[0-9A-F]|7F|8[0-46-9A-F]9[0-9A-F])";
                    break;
                case "1.1":
                    pattern = @"#x((10?|[2-F])FFF[EF]|FDD[0-9A-F]|[19][0-9A-F]|7F|8[0-46-9A-F]|0?[1-8BCEF])";
                    break;
                default:
                    throw new Exception("Error: Invalid XML Version!");
            }

            Regex regex = new Regex(pattern, RegexOptions.IgnoreCase);
            if (regex.IsMatch(tmpContents))
            {
                tmpContents = regex.Replace(tmpContents, String.Empty);
            }
            tmpContents = string.Empty;
        }
    }
}
19
ответ дан Community 15 August 2018 в 20:27
поделиться
  • 1
    Ницца. У вас есть эквивалентный метод для тех, кто использует XmlElement? – djdanlib 30 November 2011 в 21:34
  • 2
    Обновление: установка свойства InnerText объекта XmlElement позволяет избежать ошибок. Ответил мой собственный вопрос, хуза! – djdanlib 30 November 2011 в 21:46
  • 3
    Спасибо, но я читаю XML, а не пишу. Как я могу это сделать? – Alireza Noori 1 December 2011 в 00:19
  • 4
    Да, это точно проблема. – Alireza Noori 1 December 2011 в 15:08
  • 5
    Это не решило мою проблему. – Alireza Noori 1 December 2011 в 15:08
  • 6
    Вы все еще можете получить проблемы, если содержимое ваших элементов содержит недопустимые символы, такие как backspace (0x08), многие другие управляющие символы или суррогатные коды. – Jakub 31 March 2014 в 14:52

Метод RemoveInvalidXmlChars, предоставленный Irishman, не поддерживает суррогатных символов. Чтобы проверить его, используйте следующий пример:

static void Main()
{
    const string content = "\v\U00010330";

    string newContent = RemoveInvalidXmlChars(content);

    Console.WriteLine(newContent);
}

Это возвращает пустую строку, но это не должно! Он должен возвращать «\ U00010330», потому что символ U + 10330 является допустимым символом XML.

Для поддержки суррогатных символов я предлагаю использовать следующий метод:

public static string RemoveInvalidXmlChars(string text)
{
    if (string.IsNullOrEmpty(text))
        return text;

    int length = text.Length;
    StringBuilder stringBuilder = new StringBuilder(length);

    for (int i = 0; i < length; ++i)
    {
        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();
}
4
ответ дан Francois C 15 August 2018 в 20:27
поделиться

Используйте SecurityElement.Escape

using System;
using System.Security;

class Sample {
  static void Main() {
    string text = "Escape characters : < > & \" \'";
    string xmlText = SecurityElement.Escape(text);
//output:
//Escape characters : &lt; &gt; &amp; &quot; &apos;
    Console.WriteLine(xmlText);
  }
}
60
ответ дан gsamaras 15 August 2018 в 20:27
поделиться

Ниже приведен оптимизированный вариант вышеописанного метода RemoveInvalidXmlChars, который не создает новый массив для каждого вызова, тем самым подчеркивая GC необъяснимо:

public static string RemoveInvalidXmlChars(string text)
    {
        if (text == null) return text;
        if (text.Length == 0) return text;

        // a bit complicated, but avoids memory usage if not necessary
        StringBuilder result = null;
        for (int i = 0; i < text.Length; i++)
        {
            var ch = text[i];
            if (XmlConvert.IsXmlChar(ch))
            {
                result?.Append(ch);
            }
            else
            {
                if (result == null)
                {
                    result = new StringBuilder();
                    result.Append(text.Substring(0, i));
                }
            }
        }

        if (result == null)
            return text; // no invalid xml chars detected - return original text
        else
            return result.ToString();

    }
3
ответ дан Urs Meili 15 August 2018 в 20:27
поделиться
  • 1
    Что это за синтаксис ?.? в строке result?.Append(ch);? – JB. 28 August 2017 в 09:14
  • 2
    ?. - Null-Conditional Operator. [Д0] docs.microsoft.com/en-us/dotnet/csharp/language-reference/… – Pure.Krome 13 September 2017 в 03:13
19
ответ дан Community 5 September 2018 в 19:45
поделиться
Другие вопросы по тегам:

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