У меня есть объект:
class Thing {
[Xmlarray("Widget", IsNullable=true) ]
List<Widget> Widgets;
}
class Widget {
[Xmlattribute]
public string Name;
[XmlTextAttribute]
public string Value;
}
В принципе, я хочу, чтобы результат выборки выглядел следующим образом:
<Thing>
<Widget name="foo" xsi:nil="true"/>
<Widget name="bar">Nerds</Widget>
</Thing>
Проблема, которую я испытываю, заключается в том, что xmlserializer не делает этого для строки foo. Он не записывает бит xsi:nil
для виджетов, у которых есть Value
содержащее нуль. Это просто пустой элемент (<Widget name="foo"/>
Парсер, который заканчивает употребление этого Xml, является старым, и мусор и из моего контроля. Он ожидает, что nil бит будет там, если я хочу, чтобы эта запись виджетов удалялась из ее системы/хранилища и не устанавливала ее пустым (что и происходит, если нулевой бит отсутствует в пустой записи Widget).
Извините, если есть ошибки, записывая их на мобильный телефон. По сути, как мне получить xmlserializer, чтобы записать бит nil?
UPDATE: Здесь находятся теги. Я читаю смутные вещи о том, как нельзя установить nillable, если есть атрибут на arrayitem (виджет в списке Widgets).
<Widget xsi:nil="true"/>
для меня бесполезно, как я уже упоминал, для записи требуется атрибут name, а nil = true (он сообщает процессору "это поле, удаляет его из хранилища"). Без атрибута name он не знает, в каком поле. К сожалению, это зависит только от xsi: nil, чтобы сказать это. Если он видит пустой <Widget name="foo"/>
- он устанавливает его пустым/пустым, а не полностью удаляется.
class Thing{
[System.Xml.Serialization.XmlArrayItemAttribute("Widget", IsNullable=true)]
public List<Widget> Widgets { get; set; }
}
class Widget{
[System.Xml.Serialization.XmlAttribute][JsonProperty]
public string name {get;set;}
[System.Xml.Serialization.XmlTextAttribute]
public string Value {get;set;}
}
По существу это не может быть <Widget name="foo"><Value>Bar</Value></Widget>
или <Widget xsi:nil=true/>
или <Widget name="foo"/>
- должно быть <Widget name="foo" xsi:nil="true"/>
. Вините процессор, к которому эта вещь отправляется (я не контролирую).
Итак, это сериализуемо?
Я обновляю ответ и снова удаляю код. Внедрение IXmlSerializable может работать для этой проблемы. Я только реализую функцию интерфейса WriteXml, вы можете реализовать другие, если вам нужно. Код будет изменен, как утверждается:
public class Thing:IXmlSerializable
{
public List<Widget> Widgets{get;set;}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
throw new NotImplementedException();
}
public System.Xml.Schema.XmlSchema GetSchema()
{
throw new NotImplementedException();
}
public void ReadXml(System.Xml.XmlReader reader)
{
throw new NotImplementedException();
}
public void WriteXml(System.Xml.XmlWriter writer)
{
writer.WriteStartElement("xsi","Thing", @"http://www.w3.org/2001/XMLSchema-instance");
foreach (Widget widget in Widgets)
{
if (string.IsNullOrEmpty(widget.Value))
{
writer.WriteStartElement("widget");
writer.WriteAttributeString("Name", widget.Name);
writer.WriteAttributeString("xsi", "nil", @"http://www.w3.org/2001/XMLSchema-instance", "true");
writer.WriteEndElement();
}
else
{
writer.WriteStartElement("widget");
writer.WriteAttributeString("Name", widget.Name);
writer.WriteString(widget.Value);
writer.WriteEndElement();
}
}
writer.WriteEndElement();
writer.Flush();
}
}
public class Widget
{
public string Name{get;set;}
public string Value { get; set; }
}
}
public static void SaveXml()
{
XmlWriterSettings settings= new XmlWriterSettings();
settings.Indent = true;
settings.OmitXmlDeclaration = true;
XmlWriter xmlWriter = XmlWriter.Create(@"c:\test.xml",settings);
thing.WriteXml(xmlWriter);
}
После сериализации xml выглядит так: значение ниже.widget3 равно null. Надеемся, что это полезно.
<xsi:Thing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<widget Name="name1">widget1</widget>
<widget Name="name2">widget2</widget>
<widget Name="name3" xsi:nil="true" />
</xsi:Thing>