Десериализация XML строковых элементов с новыми строками в C#

Я не могу понять, почему этот тест не проходит

Тест:

учитывая следующий XML:

<?xml version="1.0" encoding="utf-8"?>
  <foo>
<account>
 1234567890
</account>
<deptCode>
 ABCXYZ
</deptCode>
</foo>

и следующий класс:

class Foo  {

  [XmlElement(ElementName = "account", DataType = "normalizedString")]
  string account;

  [XmlElement(ElementName = "deptCode", DataType = "normalizedString"]
  string deptCode;

}

когда этот XML десериализуется с помощью:

XmlSerializer serializer = new XmlSerializer(typeof(Foo));
Foo myFoo = (Foo) serializer.Deserialize(xmlReader);

Я получаю следующие значения:

Foo.account = "\r\n 1234567890 \r\n"
Foo.deptCode = "\r\n ABCXYZ \r\n"

вместо ожидаемого

Foo.account = "1234567890"
    Foo.deptCode = "ABCXYZ"

Как мне сделать так, чтобы процесс десериализации дал мне ожидаемые результаты? Я думал, что DataType="normalizedString" может это сделать, но, похоже, это не имеет никакого эффекта, и когда я использую XmlReaderSettings.IgnoreWhitespace, он просто убирает символ "\r", оставляя меня с "\n 1234567890"


person Community    schedule 20.10.2011    source источник
comment
Какой у вас код, который десериализует объекты? Вероятно, вам нужно установить некоторые параметры десериализатора.   -  person Joe White    schedule 20.10.2011
comment
добавил рассматриваемый код десериализации, единственным важным параметром, который я мог видеть, был вышеупомянутый XmlReaderSettings.IngoreWhitespace, который по-прежнему оставляет меня с новой строкой.   -  person    schedule 20.10.2011
comment
Какой тип xmlReader? Вы используете XmlTextReader?   -  person Andrew Church    schedule 20.10.2011
comment
Ни XmlReader, ни XmlTextReader не работают   -  person    schedule 20.10.2011


Ответы (3)


Кажется, он работает как задумано. Из IgnoreWhitespace документация:

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

По сути, он сохраняет (при значении false) пробелы между элементами, например:

<Foo>

<bar>Text</bar>
</Foo>

Читатель вернет новую строку между <Foo> и <bar>. Установите IgnoreWhitespace на true, и этого не произойдет.

Для достижения цели вам придется сделать программную обрезку, как сказал Кирилл. Когда вы думаете об этом, как читатель должен знать, является ли пробел чистого строкового содержимого элемента (как в ваших примерах) только для целей отступа или фактическим содержимым?

Чтобы узнать больше об игнорировании пробелов, вы можете посмотреть здесь и здесь.

person k.m    schedule 20.10.2011

Вы можете создать собственный класс XmlTextReader:

public class CustomXmlTextReader : XmlTextReader
{
    public CustomXmlTextReader(Stream stream) : base(stream) { }

    public override string ReadString()
    {
        return base.ReadString().Trim();
    }
}
person Kirill Polishchuk    schedule 20.10.2011

Попробуйте использовать XmlTextReader для десериализации со свойством WhiteSpaceHandling, установленным на WhiteSpaceHandling.None и Normalization = true.

person Andrew Church    schedule 20.10.2011
comment
к сожалению, XmlTextReader с WhiteSpaceHandling.None не повлияло - person ; 20.10.2011
comment
как насчет установки Normalization = true? По умолчанию это ложь. Я думаю, что это должно преобразовать \n в пробел. - person Andrew Church; 20.10.2011
comment
Normalization = true преобразует \r\n в \n, но оставляет там новую строку. XmlReaderSettings.IgnoreWhitespace также удаляет \r, но я не смог протестировать их комбинацию, поскольку я могу только добавить экземпляр XmlReaderSettings в обычный XmlReader, а не в XmlTextReader (конструктор не имеет параметра settings, а свойство settings нет сеттера) - person ; 20.10.2011