在运行时声明 XML 命名空间

Declaring XML Namespace at Runtime

我正在尝试为 Unity 应用程序编写脚本(用 Unityscript 编写),它能够在运行时将节点添加到 XML 文档(使用 XmlDocument class)。 我在尝试声明新节点的 'name' 属性时遇到问题。

我想知道如何使用默认 XMLNS 属性之外的名称空间创建节点(在我的例子中替换 'xmlns=''name=') 以匹配现有标记。

在 MSDN 文档上花了很多时间后,我认为这可能与 XmlNameSpaceManager 或更改默认命名空间有关,但是我正在努力理解如何实现它(仍然XML 在 Unity / uJS 中还很新)所以非常欢迎任何建议。

非常感谢,

瑞安

当前代码:

function Start(){
 //Automatically loads XML doc for save etc
 doc = new XmlDocument();
 doc.Load(Application.dataPath + "/objMetaTest01.xml");
 
 root = doc.DocumentElement;
 Debug.Log("XML Root: " + root.Name);
 
 nodeList = root.SelectNodes("MetaPipeObject");
 Debug.Log("***XML Log Begin ***");
 Debug.Log("Number of Objects: " + nodeList.Count); //returns total number of MPObjs
 
 for (var i = 0; i < nodeList.Count; i++)
 {
  var node = nodeList[i];
  //Debug.Log("Node Name: " + node.Attributes["name"].Value);
  
 }
 
 //Namespace Manager to add namespace to file
 //docNameSpace = new XmlNamespaceManager(doc.NameTable);
 //docNameSpace.AddNamespace("name", doc.DocumentElement.NamespaceURI);
 
 //Debug.Log("Doc DefaultNamespace: " + docNameSpace.DefaultNamespace);
 //Debug.Log("nmsg has 'name' prefix: " + docNameSpace.HasNamespace("name"));
 Debug.Log("***XML Log End ***");
}


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

 //select last MP node to add the new one behind 
 doc.DocumentElement.RemoveAttribute("xlmns");
 
 var lastObjNode = root.SelectSingleNode("MetaPipeObject[last()]");
 var newObjNode = doc.CreateElement("MetaPipeObject", "DogTest");
 
 //Create new attribute test
 //var nameAttr = doc.CreateAttribute("name");
 //newObjNode.Attributes.Append(nameAttr);
 //"name", "nameTest", doc.DocumentElement.NamespaceURI, doc
 
 newObjNode.InnerXml = lastObjNode.InnerXml; //copy content
 
 root.InsertAfter(newObjNode, lastObjNode); //add to the bottom of the xml doc
 
 doc.Save(Application.dataPath + "/objMetaTest01.xml");
 
 Debug.Log("New Nodes Attribute: " + newObjNode.Attributes);
 Debug.Log("New Node Namespace: " + newObjNode.NamespaceURI);
 Debug.Log("New Node Name: " + newObjNode.Name);
 Debug.Log("New node is: " + newObjNode.InnerText);
}

目前Returns

   <MetaPipeObject xmlns="DogTest">
 <FileName xmlns="">water_drop.obj</FileName>
 <Description xmlns="">Text to go here</Description>
 <Health xmlns="">10</Health>
 <Experience xmlns="">10</Experience>

我想要的结果:

  <MetaPipeObject name="DogTest">
 <FileName>water_drop.obj</FileName>
 <Description>Text to go here</Description>
 <Health>10</Health>
 <Experience>10</Experience>

查看以下链接以获得帮助

  1. Writing XML using JavaScript
  2. Create Well-Formed XML with JavaScript

经过进一步研究,结果证明创建所需 XML 格式的解决方案分为两部分,比我最初研究的路线简单得多。

  1. 首先,我使用错误的方法创建了元素;最初我使用的是 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),它只提供元素的名称。
  2. 我需要做的就是通过 SetAttribute() 分配名称属性,然后问题就解决了。

我希望这对遇到类似情况的任何人有所帮助。 NamspaceManager 是另一种可能的途径,我可以使用它并分配一个不同于默认名称空间的名称空间,但是要解决我的问题,这似乎有点过分了。

这是我最终使用的代码片段:

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"));

}