2016-11-02 4 views
0

У меня есть следующий фрагмент класса:C# XML сериализации без обертки

public class varString 
{ 
    public string KeyWord; 
    public string Value; 
    public static implicit operator string(varString v) 
    { 
     return v == null ? null : (string)v.Value; 
    } 
} 

KeyWord разрешено быть пустым.

При сериализации в XML, я получаю следующий результат, когда KeyWord равна нулю:

<varString> 
    <Value>value goes here</Value> 
</varString> 

Как я могу получить XML сериалайзер вывести следующие тогда и только тогда, когда KeyWord равно нулю ?:

<varString>value goes here</varString> 

Если KeyWord не равно нулю, я бы до сих пор нравится, чтобы вывести следующее:

<varString> 
    <!-- Can either be <Value></Value or just straight text --> 
    <KeyWord>KeyWord goes here</KeyWord> 
<varString> 

Обратите внимание, что я уже изменил события десериализации для обработки этого случая, чтобы преобразовать одиночную строку в varString с нулевым ключом.

+1

Зачем вам это нужно? Это упрощает анализ xml для получателя. –

+0

Мне легче редактировать xml таким образом. KeyWord имеет значение 9/10 раз, поэтому я бы предпочел не иметь дополнительный вывод тега. Просто личное предпочтение - это все, на самом деле ничего не влияет. – Hondros

ответ

1

Марк Value с атрибутом [XmlText]:

public class varString 
{ 
    [XmlText] 
    public string Value; 
    public string KeyWord; 
    public static implicit operator string(varString v) 
    { 
     return v == null ? null : (string)v.Value; 
    } 
} 

Образец fiddle.

+0

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

+0

@ Хондрос - просмотрите раздел [Замечания] (https://msdn.microsoft.com/en-us/library/system.xml.serialization.xmltextattribute.aspx#Remarks) раздела документов, например. * В класс может применяться только один экземпляр класса XmlTextAttribute. * И * Вы можете применить XmlTextAttribute к общедоступным полям и общедоступным свойствам чтения/записи, которые возвращают примитивные и перечисляемые типы. * – dbc

+1

Hm interesting. Я изменил вашу скрипту, чтобы увидеть, поддерживает ли она классы с определенными параметрами varStrings: https://dotnetfiddle.net/yan3ts. И это действительно работает. Я уверен, что могу понять это здесь. Спасибо! – Hondros

0

Попробуйте этот подход:

var vs = new varString(); 
vs.KeyWord = "key"; // null; 
vs.Value = "value"; 


var attr = new XmlAttributes(); 

if (vs.KeyWord == null) 
    attr.XmlText = new XmlTextAttribute(); 
else 
    attr.XmlElements.Add(new XmlElementAttribute { ElementName = "Value" }); 

var overrides = new XmlAttributeOverrides(); 
overrides.Add(typeof(varString), "Value", attr); 


var xs = new XmlSerializer(typeof(varString), overrides); 
xs.Serialize(Console.Out, vs); 

В зависимости от значения KeyWord мы добавим XmlTextAttribute или XmlElementAttribute.

+0

К сожалению, я не думаю, что это сработает для меня, потому что каждый varString будет иметь ключевое слово null в каждом конкретном случае, и я использую класс контейнера для хранения нескольких varStrings. – Hondros

+0

@ Хондрос - Да, для нескольких значений это неприменимо. –

+1

Вам нужно кэшировать сериализатор, если вы его построите с помощью 'XmlAttributeOverrides'. См. [Утечка памяти с помощью StreamReader и XmlSerializer] (https://stackoverflow.com/questions/23897145) – dbc

Смежные вопросы