How do you force explicit tag closing with Linq XML?

前端 未结 4 1124
轻奢々
轻奢々 2020-12-20 13:09

This is the same question as: Explicit Element Closing Tags with System.Xml.Linq Namespace

but I use Net 4.0 and the answers do not work anymore.

The problem i

相关标签:
4条回答
  • 2020-12-20 13:45

    I can't reproduce your error. This works as expected in both 4.0 and 3.5 netFX:

    namespace ExplicitXmlClosingTags
    {
        using System.Xml;
        using System.Xml.Linq;
    
        class Program
        {
            static void Main(string[] args)
            {
                const string ElementRoot = "RootElement";
                const string ElementChild = "ChildElement";
                const string AttributeChild = "ChildAttribute";
    
                XDocument xDoc = new XDocument();
                XElement root = new XElement(ElementRoot);
                XElement child = new XElement(ElementChild, string.Empty);
                root.Add(child);
    
                child.SetAttributeValue(AttributeChild, "AttrValue");
                xDoc.Add(root);
    
                XmlWriterSettings xws = new XmlWriterSettings();
                xws.Indent = true;
                using (XmlWriter xw = XmlWriter.Create("out.xml", xws))
                {
                    xDoc.Save(xw);    
                }
            }
        }
    }
    

    producing following content:

    <?xml version="1.0" encoding="utf-8"?>
    <RootElement>
      <ChildElement ChildAttribute="AttrValue"></ChildElement>
    </RootElement>
    
    0 讨论(0)
  • 2020-12-20 13:46
     var document = XDocument.Parse(XMLData); 
                            foreach (XElement childElement in
                            from x in document.DescendantNodes().OfType<XElement>()
                            where x.IsEmpty
                            select x)
                            {
                                childElement.Value = "";
                            }
    

    Try this its work. Just replace childElement.IsEmpty = false; with childElement.Value = "";

    0 讨论(0)
  • 2020-12-20 13:57

    set the value of the XElement to String.Empty

    OR

    setting the IsEmpty property to false for all elements not having any child nodes

        foreach (XElement childElement in
            from x in document.DescendantNodes().OfType<XElement>()
            where x.IsEmpty
            select x)
        {
            childElement.IsEmpty = false;
        }
    
    0 讨论(0)
  • 2020-12-20 13:58

    Explicitly setting the XElement value to an empty string should work. LINQ-to-XML already treats nodes without content (like new XElement("foo")) differently from nodes with content of length zero (like new XElement("foo", string.Empty)), as you can see from the documentation on XElement.IsEmpty.

    But in case that doesn't work, or in case you need to fine tune some other aspect of the XML output, you can derive a custom XmlWriter:

    public class MyWriter : XmlWriter
    {
        private readonly XmlWriter inner;
        public MyWriter(XmlWriter inner)
        {
            this.inner = inner;
        }
    
        public void Dispose()
        {
            ((IDisposable) inner).Dispose();
        }
    
        public override void WriteStartDocument()
        {
            inner.WriteStartDocument();
        }
    
        public override void WriteStartDocument(bool standalone)
        {
            inner.WriteStartDocument(standalone);
        }
    
        public override void WriteEndDocument()
        {
            inner.WriteEndDocument();
        }
    
        public override void WriteDocType(string name, string pubid, string sysid, string subset)
        {
            inner.WriteDocType(name, pubid, sysid, subset);
        }
    
        public override void WriteStartElement(string prefix, string localName, string ns)
        {
            inner.WriteStartElement(prefix, localName, ns);
        }
    
        public override void WriteEndElement()
        {
            inner.WriteFullEndElement();
        }
    
        public override void WriteFullEndElement()
        {
            inner.WriteFullEndElement();
        }
    
        public override void WriteStartAttribute(string prefix, string localName, string ns)
        {
            inner.WriteStartAttribute(prefix, localName, ns);
        }
    
        public override void WriteEndAttribute()
        {
            inner.WriteEndAttribute();
        }
    
        public override void WriteCData(string text)
        {
            inner.WriteCData(text);
        }
    
        public override void WriteComment(string text)
        {
            inner.WriteComment(text);
        }
    
        public override void WriteProcessingInstruction(string name, string text)
        {
            inner.WriteProcessingInstruction(name, text);
        }
    
        public override void WriteEntityRef(string name)
        {
            inner.WriteEntityRef(name);
        }
    
        public override void WriteCharEntity(char ch)
        {
            inner.WriteCharEntity(ch);
        }
    
        public override void WriteWhitespace(string ws)
        {
            inner.WriteWhitespace(ws);
        }
    
        public override void WriteString(string text)
        {
            inner.WriteString(text);
        }
    
        public override void WriteSurrogateCharEntity(char lowChar, char highChar)
        {
            inner.WriteSurrogateCharEntity(lowChar, highChar);
        }
    
        public override void WriteChars(char[] buffer, int index, int count)
        {
            inner.WriteChars(buffer, index, count);
        }
    
        public override void WriteRaw(char[] buffer, int index, int count)
        {
            inner.WriteRaw(buffer, index, count);
        }
    
        public override void WriteRaw(string data)
        {
            inner.WriteRaw(data);
        }
    
        public override void WriteBase64(byte[] buffer, int index, int count)
        {
            inner.WriteBase64(buffer, index, count);
        }
    
        public override void Close()
        {
            inner.Close();
        }
    
        public override void Flush()
        {
            inner.Flush();
        }
    
        public override string LookupPrefix(string ns)
        {
            return inner.LookupPrefix(ns);
        }
    
        public override WriteState WriteState
        {
            get { return inner.WriteState; }
        }
    }
    

    The relevant method is this one:

    public override void WriteEndElement()
    {
        inner.WriteFullEndElement(); // always write both start and close tags
    }
    
    0 讨论(0)
提交回复
热议问题