Declaring XML Namespace at Runtime

Hi Unity Community!

I’m trying to write a script to add nodes to an XML document at runtime however I am encountering issues when trying to define the name attribute of the new node; I would like to know how I can declare another namespace outside of the default XMLNS attribution (in my case ‘name’) to match the existing markup.

I assume this is to do with the XmlNameSpaceManager but I am struggling to understand how to implement this (still pretty new to XML in Unity / uJS).

Many thanks in advance,

Ryan

My code in its current state is:

import System.Runtime.Serialization.Formatters.Binary;
import System.IO;
import System.Xml;

public static var control : ObjInfoControl; 
public var doc : XmlDocument; 
public var root : XmlNode;
public var nodeList : XmlNodeList;
public var docNameSpace : XmlNamespaceManager;

public var health : float; //test
public var experience : float; //test
public var objName : String; //imported object name
public var fileName : String; //original file name
public var objDescript : String; //user defined description of object
public var initialObjName : String; //initial name of object chached on load



function Start(){
	//Automatically loads XML doc for save etc
	doc = new XmlDocument();
	doc.Load(Application.dataPath + "/objMetaTest01.xml");
	root = doc.DocumentElement;	
	nodeList = root.SelectNodes("MetaPipeObject");
	
	for (var i = 0; i < nodeList.Count; i++)
	{
		var node = nodeList*;	*
  • }*
    }

public function CreateNewNode(){

  • //Creates new node for new objects*

  • //will be similar to the replace function to be written soon*

  • //Namespace Manager to add namespace to file*

  • //docNameSpace = new XmlNamespaceManager(doc.NameTable);*

  • //docNameSpace.AddNamespace(“name”, doc.DocumentElement.NamespaceURI);*

  • //select last MP node to add the new one behind *

  • var lastObjNode = root.SelectSingleNode(“MetaPipeObject[last()]”);*

  • var newObjNode = doc.CreateElement(“MetaPipeObject”, “DogTest”);*

  • newObjNode.InnerXml = lastObjNode.InnerXml; //copy content*

  • root.InsertAfter(newObjNode, lastObjNode); //add to the bottom of the xml doc*

  • doc.Save(Application.dataPath + “/objMetaTest01.xml”);*
    }
    The return I am currently producing:

    water_drop.obj
    Text to go here
    10
    10

    I also tested the [three string][1] CreateElement() method with better but still not ideal results:
    <MetaPipeObject:name xmlns:MetaPipeObject=“DogTest”>
    water_drop.obj
    Text to go here
    10
    10
    </MetaPipeObject:name>
    The result I am wanting:

    water_drop.obj
    Text to go here
    10
    10

    [1]: XmlDocument.CreateElement Method (System.Xml) | Microsoft Learn

After much further research it turns out the solution to creating the desired XML format was two part and much simpler than the route I initially researched.

  1. Firstly I was creating the the element using the wrong method; initially I was using the CreateElement(string, string) which was, presumably, invoking the default namespace URI (hence all of the xmlns attributes being associated to each of the child tags). The method I really wanted was the CreateElement(string) which simply provides the name of the element.
  2. All that I needed to do was assign the name attribute via SetAttribute() and all was sorted.

I hope this helps anyone who finds themselves in a similar situation. The NamspaceManager is another possible route I could have used and assigned a different namespace other than the default, however to resolve my issue this seemed overkill.

Here is the snippet of code I ended up using:

public function CreateNewNode(){
	//Creates new node for new objects
	//will be similar to the replace function to be written soon

	var lastObjNode = root.SelectSingleNode("MetaPipeObject[last()]"); //select last MP node to add the new one behind
	
	var newObjNode = doc.CreateElement("MetaPipeObject");
	
	//Create new attribute test
	newObjNode.SetAttribute("name", objName);

	newObjNode.InnerXml = lastObjNode.InnerXml; //copy content from above listing
	
	newObjNode.SelectSingleNode("FileName").InnerText = fileName;
	newObjNode.SelectSingleNode("Description").InnerText = "No Description Added Yet";
	newObjNode.SelectSingleNode("Health").InnerText = "0";
	newObjNode.SelectSingleNode("Experience").InnerText = "0";
	
	
	root.InsertAfter(newObjNode, lastObjNode); //add to the bottom of the xml doc
	
	doc.Save(Application.dataPath + "/objMetaTest01.xml");
	
	Debug.Log("CREATED new node: " + newObjNode.GetAttribute("name"));

}