当没有数据时,防止XmlSerializer中的自闭标签

时间:2012-11-24 08:18:51

标签: c# .net xml

当我序列化值时:如果数据中没有值,那么它就像下面的格式一样。

  <Note>
        <Type>Acknowledged by PPS</Type>
        <Data />
  </Note>

但我想要的xml数据格式如下:

  <Note>
        <Type>Acknowledged by PPS</Type>
        <Data></Data>
  </Note>

代码为此,我写了:

[Serializable]
public class Notes
{
    [XmlElement("Type")]
    public string typeName { get; set; }

    [XmlElement("Data")]
    public string dataValue { get; set; }
}

如果数据没有分配任何值,我无法弄清楚如何以下面的格式实现数据。

  <Note>
        <Type>Acknowledged by PPS</Type>
        <Data></Data>
  </Note>

5 个答案:

答案 0 :(得分:11)

您可以通过创建自己的XmlTextWriter来传递进入序列化过程。

public class MyXmlTextWriter : XmlTextWriter
{
    public MyXmlTextWriter(Stream stream) : base(stream, Encoding.UTF8)
    {

    }

    public override void WriteEndElement()
    {
        base.WriteFullEndElement();
    }
}

您可以使用以下方法测试结果:

class Program
{
    static void Main(string[] args)
    {
        using (var stream = new MemoryStream())
        {
            var serializer = new XmlSerializer(typeof(Notes));
            var writer = new MyXmlTextWriter(stream);
            serializer.Serialize(writer, new Notes() { typeName = "Acknowledged by PPS", dataValue="" });
            var result = Encoding.UTF8.GetString(stream.ToArray());
            Console.WriteLine(result);
        }
       Console.ReadKey();
    }

答案 1 :(得分:1)

IMO无法使用Serialization生成所需的XML。但是,您可以使用LINQ to XML生成所需的架构 -

XDocument xDocument = new XDocument();
XElement rootNode = new XElement(typeof(Notes).Name);
foreach (var property in typeof(Notes).GetProperties())
{
   if (property.GetValue(a, null) == null)
   {
       property.SetValue(a, string.Empty, null);
   }
   XElement childNode = new XElement(property.Name, property.GetValue(a, null));
   rootNode.Add(childNode);
}
xDocument.Add(rootNode);
XmlWriterSettings xws = new XmlWriterSettings() { Indent=true };
using (XmlWriter writer = XmlWriter.Create("D:\\Sample.xml", xws))
{
    xDocument.Save(writer);
}

主要问题是in case your value is null, you should set it to empty string。它将force the closing tag to be generated。如果value为null,则不会创建结束标记。

答案 2 :(得分:0)

Kludge时间 - 请参阅Generate System.Xml.XmlDocument.OuterXml() output thats valid in HTML

基本上,在生成XML doc后,遍历每个节点,如果没有子节点,则添加一个空文本节点

// Call with
addSpaceToEmptyNodes(xmlDoc.FirstChild);

private void addSpaceToEmptyNodes(XmlNode node)
{
    if (node.HasChildNodes)
    {
        foreach (XmlNode child in node.ChildNodes)
            addSpaceToEmptyNodes(child);
    }
    else         
        node.AppendChild(node.OwnerDocument.CreateTextNode(""))
}

(是的,我知道您不应该这样做 - 但如果您将XML发送到其他一些您无法轻易解决的系统,那么必须务实处理事情)

答案 3 :(得分:0)

您可以添加虚拟字段以防止自闭元素。

[XmlText]
public string datavalue= " ";

或者如果你想要你班级的代码那么你的班级应该是这样的。

public class Notes
{
   [XmlElement("Type")]
   public string typeName { get; set; }

   [XmlElement("Data")]
   private string _dataValue;
   public string dataValue {
      get {
          if(string.IsNullOrEmpty(_dataValue))
             return " ";
          else
             return _dataValue;
      }
      set {
          _dataValue = value;
      }
   }
}

答案 4 :(得分:0)

原则上,armen.shimoon's answer为我工作。但是,如果您希望在不使用XmlWriterSettings和其他Stream对象(如注释中所述)的情况下漂亮地打印XML输出,则只需在XmlTextWriter类的构造函数中设置Formatting。

public MyXmlTextWriter(string filename) : base(filename, Encoding.UTF8)
{
    this.Formatting = Formatting.Indented;
}

(本会以评论的形式发布,但尚不允许;-))