Reputation: 946
I am trying to create the following XML string using XElement
<Issue xmlns="http://tempuri.org/">
<p>
<Nombre>no</Nombre>
<Descripcion>asdf</Descripcion>
</p>
</Issue>
I've tried the following code, but this approach adds an empty xmlns
attribute to the p
element, which I don't want:
var ns = XNamespace.Get("http://tempuri.org/");
XElement e = new XElement(ns + "Issues",
new XElement("p", new XElement("Nombre", "nme"),
new XElement("Descripcion", "dsc")));
How can I prevent this issue?
NOTE:
I cannot use XElement.Parse
like this because I need to build my soap request body dynamically:
var body = XElement.Parse("<Issue xmlns=\"http://tempuri.org/\"><p><Nombre>no</Nombre><Descripcion>asdf</Descripcion></p></Issue>");
I can't do this with a web service reference because is there an error when there exists a reference from Xamarin.
For now I am using the following workaround, but it is not the best solution, I guess:
var xdoc = new XmlDocument();
var xissue = xdoc.CreateElement("Issue");
var attr = xdoc.CreateAttribute("xmlns");
attr.Value = "http://tempuri.org/";
xissue.Attributes.Append(attr);
var xp = xdoc.CreateElement("p");
xissue.AppendChild(xp);
var xnombre = xdoc.CreateElement("Nombre");
xnombre.InnerText = "any value";
xp.AppendChild(xnombre);
var xdescription = xdoc.CreateElement("Descripcion");
xdescription.InnerText = "any value";
xp.AppendChild(xdescription);
var e = XElement.Parse(xissue.OuterXml);
Upvotes: 2
Views: 1755
Reputation: 129687
In XML, when an element does not have a namespace specified, then it inherits the namespace of its nearest ancestor that has a namespace. So, in your sample XML, the p
element and its children are actually all in the same namespace as Issue
, because they do not have an xmlns
attribute while Issue
does.
To create this same structure using XElement
, then, you need to make sure that all the elements specify the same namespace as Issue
:
var ns = XNamespace.Get("http://tempuri.org/");
XElement e = new XElement(ns + "Issue",
new XElement(ns + "p", new XElement(ns + "Nombre", "nme"),
new XElement(ns + "Descripcion", "dsc")));
XElement
is smart enough to recognize that when it is converted to string it does not need to repeat the xmlns
attribute if it matches that of its parent.
Fiddle: https://dotnetfiddle.net/QzYPoK
Conversely, if you just specify a namespace on the outer XElement
but not on the inner ones, you are actually saying that you don't want the inner elements to have a namespace at all. And so that results in an empty xmlns
attribute on the first child element: it is effectively "opting out" of the parent namespace.
Upvotes: 2