15

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

  <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>
4

5 回答 5

14

您可以通过创建自己的 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();
    }
于 2012-11-24T10:47:36.527 回答
1

IMO 不可能使用Serialization. 但是,您可以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。如果值为空,则不创建结束标记。

于 2012-11-24T10:19:34.987 回答
1

Kludge 时间 - 请参阅在 HTML 中有效的生成 System.Xml.XmlDocument.OuterXml() 输出

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

// 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 发送到您无法轻松修复的其他系统,那么您必须对事情务实)

于 2012-12-11T21:38:01.250 回答
0

原则上,armen.shimoon 的回答对我有用。但是,如果您希望在不必使用 XmlWriterSettings 和额外的 Stream 对象(如注释中所述)的情况下漂亮地打印 XML 输出,则可以简单地在 XmlTextWriter 类的构造函数中设置格式。

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

(会将此作为评论发布,但目前还不允许;-))

于 2019-06-28T11:12:35.233 回答
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;
      }
   }
}
于 2016-12-05T11:41:10.600 回答