Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/backbone.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 当不存在数据时,防止XmlSerializer中的自动关闭标记_C#_.net_Xml - Fatal编程技术网

C# 当不存在数据时,防止XmlSerializer中的自动关闭标记

C# 当不存在数据时,防止XmlSerializer中的自动关闭标记,c#,.net,xml,C#,.net,Xml,当我序列化值时:如果for data中没有值,那么它的格式如下 <Note> <Type>Acknowledged by PPS</Type> <Data /> </Note> 如果数据没有赋值,我无法计算如何实现以下格式的数据 <Note> <Type>Acknowledged by PPS</Type> <Data

当我序列化值时:如果for data中没有值,那么它的格式如下

  <Note>
        <Type>Acknowledged by PPS</Type>
        <Data />
  </Note>
如果数据没有赋值,我无法计算如何实现以下格式的数据

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

PPS认可

在我看来,使用
序列化来生成所需的XML是不可能的。但是,您可以使用
linqtoxml
生成如下所需的模式-

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);
}

主捕获是
,如果您的值为空,则应将其设置为空字符串。它将
强制生成结束标记
。如果值为null,则不会创建结束标记。

您可以通过创建自己的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();
    }
乱七八糟的时间-见

基本上,在生成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发送到其他一些你无法轻松修复的系统,那么你必须实事求是)

你可以添加一个虚拟字段来防止自动关闭元素

[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;
      }
   }
}
原则上,他为我工作。但是,如果您希望XML输出能够很好地打印出来,而不必使用XmlWriterSettings和其他Stream对象(如注释中所述),那么只需在XmlTextWriter类的构造函数中设置格式即可

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

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

虽然我不确定您为什么要这样做,但请注意,您编写的xml实际上是无效的。您永远不会关闭数据元素。如果我使用它,那么[XmlElementAttribute(IsNullable=false)]完全忽略我不希望和之间的差异很小的时候,通常直接与不完整/错误的实现联系在一起。为什么要这样做?因为我正在执行一些操作,如果在value中找不到元素,则您应该阅读我的答案并将其应用于您的情况。注意:序列化/反序列化时,这将导致
null->“
”。但是,生成XML时,每个元素后都不会断行:(@SuperJMN您需要围绕
XmlWriter
。底层
XmlWriter
需要
XmlWriter设置
Indent
设置为
true
,并将
NewLineChars
设置为合理的值。例如:(也适用于
Stream
而不是
textwitter
)它有一个缩进模式的包。这对我有效。我必须将
if(node.HasChildNodes)
更改为
if(node.HasChildNodes&&node.NodeType!=XmlNodeType.Text)
”仍然是值。
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;
      }
   }
}
public MyXmlTextWriter(string filename) : base(filename, Encoding.UTF8)
{
    this.Formatting = Formatting.Indented;
}