【问题标题】:Removing extra space in empty elements in XDocument.ToString()删除 XDocument.ToString() 中空元素中的额外空间
【发布时间】:2019-06-04 17:15:53
【问题描述】:

我正在向无法处理标记中的空格的系统发送 XML 消息。值中的空格是可以的。我一直在使用 linq/XDocument/XElements 来操作/生成消息。

问题是元素为空时。例如:

XDocument xdoc = XDocument.Parse("<root><value/></root>");
Console.WriteLine(xdoc.ToString(SaveOptions.DisableFormatting));

这会在元素标题之后的标记中输出一个带有空格的字符串,即使 DisableFormatting 已打开。

<root><value /></root>

所以我只是在上面贴了一个替换:

Console.WriteLine(xdoc.ToString(SaveOptions.DisableFormatting).Replace(" />","/>"));

有什么不好的地方我会遇到吗?有没有明显/更标准的方法来做到这一点?看起来很卡。

【问题讨论】:

    标签: c# linq-to-xml


    【解决方案1】:

    如果您的目标系统以与自关闭 xml 元素相同的方式处理空 xml 元素 - 通常,两者都被认为是相等的(但请考虑post 的备注) -你可以实现一个自定义的XmlWriter,它将自动关闭的xml标签输出为空的xml标签。
    空 xml 标记不会在其标记中包含任何空格,例如。 &lt;value&gt;&lt;/value&gt;.

    以下示例中的自定义 XmlTextWriter 生成以下 xml。
    请注意&lt;value&gt;&lt;/value&gt; 标签,valueWithWhitespace 的空白值已被保留。

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

    【讨论】:

      【解决方案2】:

      也可以用不同的方式完成,如果你对额外的缓冲没问题(使用 String.Replace,看起来你是):

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

      然后你可以把它从内存流中取出。字符串替换的不同之处在于这种方法不会破坏 CDATA 部分之类的内容。使用完整结束标签的不同之处在于,它可能会更接近地重现您已解析的内容。

      【讨论】:

        猜你喜欢
        • 2013-04-19
        • 1970-01-01
        • 2014-05-06
        • 1970-01-01
        • 1970-01-01
        • 2018-04-11
        • 1970-01-01
        • 1970-01-01
        • 2021-12-08
        相关资源
        最近更新 更多