简体   繁体   中英

Creating XML Elements without namespace declarations

I attempting to add a new "PropertyGroup" element to the following XML file

<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
  <PropertyGroup>
    <ProjectGuid>{00AA7ECA-95A0-0000-0000-AD4D2E056BFE}</ProjectGuid>
    <OutputType>Library</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>testnS</RootNamespace>
    <AssemblyName>testname</AssemblyName>
    <PluginId>4B84E5C0-EC2B-4C0C-8B8E-3FAEB09F74C6</PluginId>
  </PropertyGroup>
</Project>

The code I am using is as follows (note there is other logic that has been removed) :

        XmlTextReader reader = new XmlTextReader(filename);
        XmlDocument doc = new XmlDocument();

        doc.Load(reader);
        reader.Close();

        XmlNamespaceManager ns = new XmlNamespaceManager(doc.NameTable);
        ns.AddNamespace("x", "http://schemas.microsoft.com/developer/msbuild/2003");

        XmlElement root = doc.DocumentElement;
        XmlNode refNode = root.SelectSingleNode("x:Project", ns);

        root.SelectSingleNode("Project", ns);

        XmlElement newElement = doc.CreateElement("PropertyGroup", "http://schemas.microsoft.com/developer/msbuild/2003");
        newElement.InnerXml = "<value>test</value>";
        root.InsertAfter(newElement, refNode);
        doc.Save(filename);

This yields the following new element in the XML document :

<PropertyGroup>
  <value xmlns="">test</value>
</PropertyGroup>

How do I get rid of the namespace declaration on the element?

You need to specify the XML namespace for all elements you add to the DOM:

XmlNamespaceManager ns = new XmlNamespaceManager(doc.NameTable);
ns.AddNamespace("x", "http://schemas.microsoft.com/developer/msbuild/2003");

XmlElement root = doc.DocumentElement;
XmlNode refNode = root.SelectSingleNode("x:Project", ns);

XmlElement newElement = doc.CreateElement(
    "PropertyGroup",
    "http://schemas.microsoft.com/developer/msbuild/2003");
var value = newElement.AppendChild(doc.CreateElement(
    "value",
    "http://schemas.microsoft.com/developer/msbuild/2003"));
value.AppendChild(doc.CreateTextNode("test"));

root.InsertAfter(newElement, refNode);

If you don't do so for any element (or if you use InnerXml like that), that element will get the dreaded empty namespace.

The reason this is happening is that you've defined the default namespace for the document to be " http://schemas.microsoft.com/developer/msbuild/2003 " by having the namespace definition on the root node:

xmlns="http://schemas.microsoft.com/developer/msbuild/2003"

You then proceed to add an element which is in no namespace (the 'null' namespace) to the document. This has to be qualified with

xmlns=""

because if it wasn't it would mean that the new element was in the previously mentioned Microsoft namespace - which it isn't (or rather - which you haven't asked it to be).

So either:

  • you actually want the new element to be in the Microsoft namespace - in which case you need to say so. The easiest way is to use createElement and supply the namespace, although you can probably state it explicitly with an xmlns attribute on your InnerXml (which is not a particularly nice way of adding nodes).

  • You really do want this element in the null namespace, in which case you are probably better of qualifying all the other nodes that are not in the null namespace with a namespace prefix.

I suspect you want the former.

A quick overview on namespaces can be found here .

To avoid extra xmlns="" attribute in newly created elements you can pass root namespace as an argument:

 $child = $doc.CreateElement("value", $doc.DocumentElement.NamespaceURI);
 $res = $doc.PropertyGroup.AppendChild($child); # res here to avoid extra output

which will result in

<PropertyGroup>
    <value></value>
</PropertyGroup>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM