简体   繁体   中英

How do I collapse empty xml tags?

I'm getting XML like this:

<Items> <Row attr1="val"></Row> <Row attr1="val2"></Row> </Items>

This is valid XML, as you know, but another library I'm using is busted and it will only accept XML in this format:

<Items> <Row attr1="val"/> <Row attr1="val2"/> </Items>

I'm already reading the XML into XmlDocuments, manipulating them, and rewriting them using an XmlWriter(), what's the easiest (and most efficient) way for me to "collapse" these empty tags?

将要折叠的每个XmlElement的IsEmpty属性设置为true。

If you use System.XML's DOM manipulation objects (XmlElement etc) instead of XmlWriter, you get this for free.

XmlElement items = xmlDoc.SelectNodes("items");
XmlElement row = xmlDoc.CreateElement("row");
items[0].appendChild(row);

You'll get a "<row/>"

You can try this.

Subclass XmlTextWriter with an implementation whose WriteFullEndElement calls base.WriteEndElement. Like this:

    public class BetterXmlTextWriter : XmlTextWriter
    {
        public BetterXmlTextWriter(TextWriter w)
            : base(w)
        {
        }

        public override void WriteFullEndElement()
        {
            base.WriteEndElement();
        }
    }

Then write the document out to an instance of your subclass using XmlDocument.WriteContentTo.

If you're already using an XmlWriter to write your XML, it should already be collapsing empty elements. This code (using .Net 3.5):

XmlWriter xw = XmlWriter.Create(Console.Out);
xw.WriteStartElement("foo");
xw.WriteAttributeString("bar", null, "baz");
xw.WriteEndElement();
xw.Flush();
xw.Close();

emits <foo bar='baz' /> .

If your XmlWriter isn't, you should check to make sure that your XmlWriter code isn't emitting text nodes that you aren't expecting.

Here's a recursive method:

private static void FormatEmptyNodes(XmlNode rootNode)
{
    foreach (XmlNode childNode in rootNode.ChildNodes)
    {
        FormatEmptyNodes(childNode);

        if(childNode is XmlElement)
        {
            XmlElement element = (XmlElement) childNode;
            if (string.IsNullOrEmpty(element.InnerText)) element.IsEmpty = true;
        }
    }
}

Used like this:

var doc = new XmlDocument();
doc.Load(inputFilePath);
FormatEmptyNodes(doc);
doc.Save(outputFilePath);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM