C# 删除XDocument.ToString()中空元素中的额外空间
我正在向一个无法处理标记中空格的系统发送XML消息。值中的空格可以。我一直在使用linq/XDocument/XElements来操作/生成消息 问题是当元素为空时。例如:C# 删除XDocument.ToString()中空元素中的额外空间,c#,linq-to-xml,C#,Linq To Xml,我正在向一个无法处理标记中空格的系统发送XML消息。值中的空格可以。我一直在使用linq/XDocument/XElements来操作/生成消息 问题是当元素为空时。例如: XDocument xdoc = XDocument.Parse("<root><value/></root>"); Console.WriteLine(xdoc.ToString(SaveOptions.DisableFormatting)); 所以我在上面贴了一个替代品: Conso
XDocument xdoc = XDocument.Parse("<root><value/></root>");
Console.WriteLine(xdoc.ToString(SaveOptions.DisableFormatting));
所以我在上面贴了一个替代品:
Console.WriteLine(xdoc.ToString(SaveOptions.DisableFormatting).Replace(" />","/>"));
我在那里会遇到什么不好的事情吗?是否有一种明显的/更标准的方法来做到这一点?看起来JAG.< /P> < P>如果您的目标系统以与自关闭XML元素相同的方式处理空XML元素——一般来说,两者都被认为是相等的(但是请考虑下面的注释)——您可以实现一个自定义的<代码> XmlWriter < /C> >,它将自封的XML标签输出为空的XML标签。 空xml标记不会在其标记中包含任何空格,例如
下面示例中的自定义XmlTextWriter
生成以下xml。请注意
标记以及值WithWhitespace
的空白值已被保留
<root><value></value><valueWithWhitespace> </valueWithWhitespace></root>
如果您对额外的缓冲(使用String.Replace,看起来是这样的),也可以用另一种方式完成: 然后您可以将其从内存流中取出。stringreplace的不同之处在于,这种方法不会破坏像CDATA节这样的内容。使用完全结束标记的区别在于,它可能会更紧密地再现您解析的内容
<root><value></value><valueWithWhitespace> </valueWithWhitespace></root>
var xml = XElement.Parse(
"<root><value /><valueWithWhitespace> </valueWithWhitespace></root>",
LoadOptions.PreserveWhitespace
);
var stringWriter = new StringWriter();
using (var xmlWriter = new CustomXmlTextWriter(stringWriter))
{
xml.WriteTo(xmlWriter);
xmlWriter.Flush();
Console.WriteLine(stringWriter);
}
public class CustomXmlTextWriter : XmlTextWriter
{
public CustomXmlTextWriter(TextWriter writer)
: base(writer)
{}
public CustomXmlTextWriter(Stream stream, Encoding encoding)
: base(stream, encoding)
{}
public CustomXmlTextWriter(string filename, Encoding encoding)
: base(filename, encoding)
{}
public override void WriteEndElement()
{
this.WriteFullEndElement();
}
}
class CustomXmlTextWriter : XmlTextWriter {
public CustomXmlTextWriter(MemoryStream stream) : base(stream, new UTF8Encoding(false)) { }
public override void WriteEndElement() {
base.WriteEndElement();
base.Flush();
var stream = (MemoryStream)BaseStream;
var buffer = stream.GetBuffer();
var pos = stream.Position;
if (pos > 3 && buffer[pos - 1] == '>' && buffer[pos - 2] == '/' && buffer[pos - 3] == ' ') {
stream.Seek(-3, SeekOrigin.Current);
stream.WriteByte((byte)'/');
stream.WriteByte((byte)'>');
}
}
}