简体   繁体   English

创建没有命名空间声明的 XML 元素

[英]Creating XML Elements without namespace declarations

I attempting to add a new "PropertyGroup" element to the following XML file我尝试向以下 XML 文件添加新的“PropertyGroup”元素

<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 :这会在 XML 文档中产生以下新元素:

<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:您需要为添加到 DOM 的所有元素指定 XML 命名空间:

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.如果您不对任何元素这样做(或者如果您像这样使用InnerXml ),则该元素将获得可怕的空命名空间。

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:发生这种情况的原因是您已通过在根节点上定义命名空间,将文档的默认命名空间定义为“ http://schemas.microsoft.com/developer/msbuild/2003 ”:

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).因为如果不是,则意味着新元素在前面提到的 Microsoft 命名空间中 - 它不是(或者更确切地说 - 你没有要求它)。

So either:所以要么:

  • you actually want the new element to be in the Microsoft namespace - in which case you need to say so.您实际上希望新元素位于 Microsoft 命名空间中 - 在这种情况下,您需要这么说。 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).最简单的方法是使用 createElement 并提供命名空间,尽管您可以使用 InnerXml 上的 xmlns 属性显式声明它(这不是一种特别好的添加节点的方法)。

  • 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:为了避免在新创建的元素中出现额外的xmlns=""属性,您可以将根命名空间作为参数传递:

 $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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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