Лучший способ закодировать текстовые данные для XML

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


Общее правило для размещения typename в основном, когда вы используете параметр шаблона, и хотите получить доступ к вложенному typedef или с использованием псевдонима, например:

template
struct test {
    using type = T; // no typename required
    using underlying_type = typename T::type // typename required
};

Обратите внимание, что это также относится к метафункциям или вещи, которые также принимают общие параметры шаблона. Однако, если предоставленный параметр шаблона является явным типом, вам не нужно указывать typename, например:

template
struct test {
    // typename required
    using type = typename std::conditional::type;
    // no typename required
    using integer = std::conditional::type;
};

Общие правила добавления определителя template в основном аналогичны, за исключением они обычно включают шаблонные функции-члены (статические или другие) структуры / класса, которые сами шаблоны, например:

Учитывая эту структуру и функцию:

template
struct test {
    template
    void get() const {
        std::cout << "get\n";
    }
};

template
void func(const test& t) {
    t.get(); // error
}

Попытка доступа t.get() изнутри функции приведет к ошибке:

main.cpp:13:11: error: expected primary-expression before 'int'
     t.get();
           ^
main.cpp:13:11: error: expected ';' before 'int'

Таким образом, в этом контексте вам понадобится ключевое слово template заранее и вызвать его так:

t.template get()

Таким образом, компилятор будет анализировать это правильно, а не t.get < int.

67
задан Blorgbeard 14 May 2013 в 23:52
поделиться

8 ответов

System.XML обрабатывает кодирование для Вас, таким образом, Вам не нужен метод как это.

3
ответ дан MusiGenesis 24 November 2019 в 14:29
поделиться

Если это - приложение ASP.NET, почему бы не использовать Сервер. HtmlEncode ()?

3
ответ дан Kev 24 November 2019 в 14:29
поделиться

Это могло бы иметь место, где Вы могли извлечь выгоду из использования метода WriteCData.

public override void WriteCData(string text)
    Member of System.Xml.XmlTextWriter

Summary:
Writes out a <![CDATA[...]]> block containing the specified text.

Parameters:
text: Text to place inside the CDATA block.

А простой пример был бы похож на следующее:

writer.WriteStartElement("name");
writer.WriteCData("<unsafe characters>");
writer.WriteFullEndElement();

результат похож:

<name><![CDATA[<unsafe characters>]]></name>

При чтении узла оценивает XMLReader, автоматически разделяет часть CData innertext, таким образом, Вы не должны волноваться об этом. Единственная выгода - то, что необходимо хранить данные, поскольку innerText оценивает узлу XML. Другими словами, Вы не можете вставить содержание CData в значение атрибута.

3
ответ дан Dscoduc 24 November 2019 в 14:29
поделиться

SecurityElement. Escape

зарегистрировал здесь

31
ответ дан Brad C 24 November 2019 в 14:29
поделиться

В прошлом я использовал HttpUtility. HtmlEncode для кодирования текста для xml. Это выполняет ту же задачу, действительно. Я не имею, столкнулся с любыми проблемами с ним все же, но но это вовсе не значит я не буду в будущем. Поскольку имя подразумевает, это было сделано для HTML, не XML.

Вы, вероятно, уже читали, это, но вот является статья о xml кодированием и декодированием.

РЕДАКТИРОВАНИЕ: Конечно, при использовании xmlwriter или одного из новых классов XElement это кодирование сделано для Вас. На самом деле Вы могли просто взять текст, поместить его в новый экземпляр XElement, затем возвратить строку (.tostring) версия элемента. Я услышал тот SecurityElement. Escape выполнит ту же задачу как Ваш служебный метод также, но не читал очень об этом или использовал его.

EDIT2: Игнорируйте мой комментарий о XElement, так как Вы находитесь все еще на 2,0

26
ответ дан Kilhoffer 24 November 2019 в 14:29
поделиться

XmlTextWriter.WriteString() делает выход.

5
ответ дан GSerg 24 November 2019 в 14:29
поделиться

Depending on how much you know about the input, you may have to take into account that not all Unicode characters are valid XML characters.

Both Server.HtmlEncode and System.Security.SecurityElement.Escape seem to ignore illegal XML characters, while System.XML.XmlWriter.WriteString throws an ArgumentException when it encounters illegal characters (unless you disable that check in which case it ignores them). An overview of library functions is available here.

Edit 2011/8/14: seeing that at least a few people have consulted this answer in the last couple years, I decided to completely rewrite the original code, which had numerous issues, including horribly mishandling UTF-16.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

/// <summary>
/// Encodes data so that it can be safely embedded as text in XML documents.
/// </summary>
public class XmlTextEncoder : TextReader {
    public static string Encode(string s) {
        using (var stream = new StringReader(s))
        using (var encoder = new XmlTextEncoder(stream)) {
            return encoder.ReadToEnd();
        }
    }

    /// <param name="source">The data to be encoded in UTF-16 format.</param>
    /// <param name="filterIllegalChars">It is illegal to encode certain
    /// characters in XML. If true, silently omit these characters from the
    /// output; if false, throw an error when encountered.</param>
    public XmlTextEncoder(TextReader source, bool filterIllegalChars=true) {
        _source = source;
        _filterIllegalChars = filterIllegalChars;
    }

    readonly Queue<char> _buf = new Queue<char>();
    readonly bool _filterIllegalChars;
    readonly TextReader _source;

    public override int Peek() {
        PopulateBuffer();
        if (_buf.Count == 0) return -1;
        return _buf.Peek();
    }

    public override int Read() {
        PopulateBuffer();
        if (_buf.Count == 0) return -1;
        return _buf.Dequeue();
    }

    void PopulateBuffer() {
        const int endSentinel = -1;
        while (_buf.Count == 0 && _source.Peek() != endSentinel) {
            // Strings in .NET are assumed to be UTF-16 encoded [1].
            var c = (char) _source.Read();
            if (Entities.ContainsKey(c)) {
                // Encode all entities defined in the XML spec [2].
                foreach (var i in Entities[c]) _buf.Enqueue(i);
            } else if (!(0x0 <= c && c <= 0x8) &&
                       !new[] { 0xB, 0xC }.Contains(c) &&
                       !(0xE <= c && c <= 0x1F) &&
                       !(0x7F <= c && c <= 0x84) &&
                       !(0x86 <= c && c <= 0x9F) &&
                       !(0xD800 <= c && c <= 0xDFFF) &&
                       !new[] { 0xFFFE, 0xFFFF }.Contains(c)) {
                // Allow if the Unicode codepoint is legal in XML [3].
                _buf.Enqueue(c);
            } else if (char.IsHighSurrogate(c) &&
                       _source.Peek() != endSentinel &&
                       char.IsLowSurrogate((char) _source.Peek())) {
                // Allow well-formed surrogate pairs [1].
                _buf.Enqueue(c);
                _buf.Enqueue((char) _source.Read());
            } else if (!_filterIllegalChars) {
                // Note that we cannot encode illegal characters as entity
                // references due to the "Legal Character" constraint of
                // XML [4]. Nor are they allowed in CDATA sections [5].
                throw new ArgumentException(
                    String.Format("Illegal character: '{0:X}'", (int) c));
            }
        }
    }

    static readonly Dictionary<char,string> Entities =
        new Dictionary<char,string> {
            { '"', "&quot;" }, { '&', "&amp;"}, { '\'', "&apos;" },
            { '<', "&lt;" }, { '>', "&gt;" },
        };

    // References:
    // [1] http://en.wikipedia.org/wiki/UTF-16/UCS-2
    // [2] http://www.w3.org/TR/xml11/#sec-predefined-ent
    // [3] http://www.w3.org/TR/xml11/#charsets
    // [4] http://www.w3.org/TR/xml11/#sec-references
    // [5] http://www.w3.org/TR/xml11/#sec-cdata-sect
}

Unit tests and full code can be found here.

77
ответ дан Community 24 November 2019 в 14:29
поделиться

Библиотека Microsoft AntiXss Класс AntiXssEncoder в System.Web.dll имеет методы для этого:

AntiXss.XmlEncode(string s)
AntiXss.XmlAttributeEncode(string s)

он также имеет HTML:

AntiXss.HtmlEncode(string s)
AntiXss.HtmlAttributeEncode(string s)
14
ответ дан 24 November 2019 в 14:29
поделиться
Другие вопросы по тегам:

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