Search code examples
c#xmllinq-to-xmlxml-namespaces

How can I remove an xmlns from an element or avoid adding it when creating it


I need to create XM that looks like this.

<trajectorys xmlns="http://www.witsml.org/schemas/1series" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.4.1.1">
  <trajectory uidWell="b213fb5d-d203-41e3-8d03-64d71d5d19c2" uidWellbore="c8ede8d3-7838-4287-aad2-3da717150dff" uid="31EXX40">
  </trajectory>
</trajectorys>

My code is.

var xDoc = new XDocument();
XNamespace ns1 = "http://www.witsml.org/schemas/1series";
XNamespace ns2 = "http://www.w3.org/2001/XMLSchema-instance";
var root = new XElement(ns1 + "trajectorys",
    new XAttribute("xmlns", "http://www.witsml.org/schemas/1series"),
    new XAttribute(XNamespace.Xmlns.GetName("xsi"), "http://www.w3.org/2001/XMLSchema-instance"),
    new XAttribute("version", "1.4.1.1"));

xDoc.Add(root);

var trajectory = new XElement("trajectory",
    new XAttribute("uidWell", "b213fb5d-d203-41e3-8d03-64d71d5d19c2"),
    new XAttribute("uidWellbore", "c8ede8d3-7838-4287-aad2-3da717150dff"),
    new XAttribute("uid", "31EXX40"));

trajectory.Name = trajectory.Name.LocalName;    // try to remove xmlns
root.Add(trajectory);

Which gives me

<trajectorys xmlns="http://www.witsml.org/schemas/1series" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.4.1.1">
  <trajectory uidWell="b213fb5d-d203-41e3-8d03-64d71d5d19c2" uidWellbore="c8ede8d3-7838-4287-aad2-3da717150dff" uid="31EXX40" xmlns="">
  </trajectory>
</trajectorys>

As you can see, an extra xmlns has been added to the trajectory element, and my attempt to remove it, as recommended in other posts, has failed. The XML document that is created is read by another program, which will fail to process it properly if the xmlns is not removed. Perhaps my code can be tweaked so that itis not added to the trajectory element.


Solution

  • You need to create the <trajectory> element in the required namespace. An XElement will not inherit its namespace from its parent, so if you create it without specifying a namespace, it will go into the empty namespace.

    Thus if you modify your code as follows:

    var trajectory = new XElement(root.Name.Namespace + "trajectory", // Create it in the same namespace as the root
        new XAttribute("uidWell", "b213fb5d-d203-41e3-8d03-64d71d5d19c2"),
        new XAttribute("uidWellbore", "c8ede8d3-7838-4287-aad2-3da717150dff"),
        new XAttribute("uid", "31EXX40"));
    

    You will get

    <trajectorys xmlns="http://www.witsml.org/schemas/1series" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.4.1.1">
      <trajectory uidWell="b213fb5d-d203-41e3-8d03-64d71d5d19c2" uidWellbore="c8ede8d3-7838-4287-aad2-3da717150dff" uid="31EXX40" />
    </trajectorys>
    

    Which is semantically identical to your required XML. Note however that the <trajectory /> is self closing but your required XML shows it to have separate opening and closing tags. If you require that for some reason, specify an empty value:

    var trajectory = new XElement(root.Name.Namespace + "trajectory", // Create it in the same namespace as the root
        "", // Empty value to force distinct opening and closing tags
        new XAttribute("uidWell", "b213fb5d-d203-41e3-8d03-64d71d5d19c2"),
        new XAttribute("uidWellbore", "c8ede8d3-7838-4287-aad2-3da717150dff"),
        new XAttribute("uid", "31EXX40"));
    

    The trajectory.Name = trajectory.Name.LocalName; line is unnecessary.

    Demo fiddle here.