0

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.

greenfeet
  • 677
  • 1
  • 7
  • 27

2 Answers2

1

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.

H H
  • 263,252
  • 30
  • 330
  • 514
0

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.

Matt Hogan-Jones
  • 2,981
  • 1
  • 29
  • 35
  • is there any way to not add the namespace declaration to the new XElement? The container to which "positions" will be added to contains the namespace declaration..I just need the new XElement to have the prefix like "dyn:Positions" – greenfeet Feb 26 '19 at 14:46
  • If you're creating an XElement on it's own, then you're either going to need to add the namespace declaration or you're going to leave it as the default namespace, as in Henk Holterman's answer above. You can't create a stand alone XElement and have a namespace prefix without having a namespace declaration. – Matt Hogan-Jones Feb 26 '19 at 14:58
  • that means tho, that even tho I have this individual XElement with the namespace declaration, when I eventually append it to the root that also has the namespace declared, it will look right with the prefix like I expect it? I will test this – greenfeet Feb 26 '19 at 15:04
  • @greenfeet I just did a test and unfortunately the appended element still has the namespace declaration. I'm trying to think of a way around that - but if you're creating the `Positions` element as a stand alone element first and you want it to have the `dyn` prefix then you have to declare the `dyn` namespace. – Matt Hogan-Jones Feb 26 '19 at 15:06
  • @greenfeet found out that there's a save option to remove duplicated namespace declarations, if that's any help. – Matt Hogan-Jones Feb 26 '19 at 15:15