Xmlserializer可以使用xmlattribute填充nillable元素吗?

时间:2014-12-04 00:38:07

标签: c# .net xmlserializer

我有一个对象:

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包含null的小部件写出Value位。它只是一个空元素(<Widget name="foo"/>

最终吃掉这个Xml的解析器已经过时了,而垃圾又不受控制。如果我希望从其系统/存储中删除该窗口小部件记录而不是将其设置为空(如果空的Widget条目中缺少nil位,则会发生这种情况),它期望nil位存在。

对不起,如果有错误,请用手机写。基本上我如何让xmlserializer写入nil位?

更新:这是实际的标签。如果在arrayitem上有一个属性(Widgets列表中的Widget),我正在阅读有关如何无法设置nillable的模糊内容。

<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"/>。归咎于这个东西被送到的处理器(我无法控制)。

那么,它是否可序列化?

1 个答案:

答案 0 :(得分:2)

我更新答案,并删除不再相关的代码。实现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>