Thursday, September 26, 2019

Conditionally added XML element

On a project I'm working on we have to generate some XML documents with a pretty complex structure. In previous version we used XmlDocument, but the code is pretty verbose, so I checked XDocument alternative from Linq to XML.

This new solution works better (looks like is even faster), but I was looking for a simple solution to skip empty nodes. We didn't want <node></node> or <node />.

So in the end I tried something like this:
using System;
using System.Linq;
using System.Xml.Linq;
namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            var b3 = string.Empty; // "3"
            XDocument x = new XDocument(
                new XDeclaration("1.0", "utf-8", null),
                new XElement("a",
                    new XElement("b1", "1"),
                    ElemString("b2", "2"),
                    ElemString("b3", b3),
                    new XElement("b4", string.Empty),
                    new XElement("b5", null),
                    ElemChildren("c", ElemString("c1", "11"), ElemString("c2", string.Empty)),
                    ElemChildren("d", ElemString("d1", string.Empty), ElemString("d2", string.Empty))
                )
            );
            x.Save(Console.Out);
            Console.ReadKey();
        }
        static XElement ElemChildren(string name, params object[] children) {
            return children.Where( obj => obj != null).Any() ? new XElement(name, children) : null;
        }
        static XElement ElemString(string name, string val) {
            return string.IsNullOrEmpty(val) ? null : new XElement(name, val);
        }
    }
}
which produces:
<?xml version="1.0" encoding="utf-8"?>
<a>
  <b1>1</b1>
  <b2>2</b2>
  <b4></b4>
  <b5 />
  <c>
    <c1>11</c1>
  </c>
</a> 
ElemChildren() was used to exclude a node having all children Null, while ElemString() is a simple ternary function (here's only for strings, most important part).
Notice the difference between <b4></b4> and <b5 />. Also notice that node <d> is missing completely because of all Null children nodes.

No comments:

Post a Comment