Reputation: 677
I'm trying to create a simple empty XElement like this:
<dyn:Positions>
<Vector2-Array>
</Vector2-Array>
</dyn:Positions>
I have the namespace defined above:
XNamespace dyn = "https://www.abc.at/dyn";
But when I create the XElement:
XElement positions = new XElement(dyn + "Positions", new XElement("Vector2-Array"));
It comes out like this:
<Positions xmlns="dyn">
<Vector2-Array xmlns="" />
</Positions>
Is that possible without wrapping it in another XElement? Because I need this element to be appended in another document later, after more elements are added inside.
Upvotes: 0
Views: 492
Reputation: 3103
Because you're not adding your namespace declaration, the dyn
namespace becomes the default.
Then, when you add the child element without a namespace, a namespace declaration with no namespace has to be added to indicate it is not within the default namespace.
If your dyn
namespace is not meant to be the default namespace, try the following code:
XNamespace dyn = "https://www.abc.at/dyn";
XElement positions = new XElement(
dyn + "Positions",
new XAttribute(XNamespace.Xmlns + "dyn", "https://www.abc.at/dyn"),
new XElement("Vector2-Array"));
This produces the following output:
<dyn:Positions xmlns:dyn="https://www.abc.at/dyn">
<Vector2-Array />
</dyn:Positions>
Note that when you start appending this element to other documents, you may get more behaviour similar to your original problem if there's any mismatches of namespaces.
The OP has specifically brought up the subject of appending this element to another element that also contains the namespace declaration.
I've created this code to test:
XNamespace dyn = "https://www.abc.at/dyn";
XElement positions = new XElement(
dyn + "Positions",
new XAttribute(XNamespace.Xmlns + "dyn", "https://www.abc.at/dyn"),
new XElement("Vector2-Array"));
XElement root = new XElement(
dyn + "root",
new XAttribute(XNamespace.Xmlns + "dyn", "https://www.abc.at/dyn"));
root.Add(positions);
When using the debugger, the XML of the root
element after adding Positions
is this:
<dyn:root xmlns:dyn="https://www.abc.at/dyn">
<dyn:Positions xmlns:dyn="https://www.abc.at/dyn">
<Vector2-Array />
</dyn:Positions>
</dyn:root>
So the namespace declaration is duplicated.
However, there is a SaveOption
of OmitDuplicateNamespaces
that can be used when saving or formatting the XML to string:
Console.WriteLine(root.ToString(SaveOptions.OmitDuplicateNamespaces));
The resulting output of this is as below:
<dyn:root xmlns:dyn="https://www.abc.at/dyn">
<dyn:Positions>
<Vector2-Array />
</dyn:Positions>
</dyn:root>
Because the duplicate namespace declarations effectively do nothing (even though they're ugly) they can be removed this way, if the displaying of the XML is the important thing.
Functionally, having duplicated namespace declarations doesn't actually do anything as long as they match.
Upvotes: 1
Reputation: 273244
I think you want Vector2-Array to be in the same namespace as Positions, and then you don't see it in the output:
XElement positions = new XElement(dyn + "Positions",
new XElement(dyn + "Vector2-Array"));
this gives
<Positions xmlns="https://www.abc.at/dyn">
<Vector2-Array />
</Positions>
the dyn:
notation is just a shorthand, it should not matter when you later merge this in some parent XML. You should be very sure about which namespace everything belongs to.
Upvotes: 1