[英]Creating XML Elements without namespace declarations
我尝试向以下 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>
我使用的代码如下(注意有其他逻辑已被删除):
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);
这会在 XML 文档中产生以下新元素:
<PropertyGroup>
<value xmlns="">test</value>
</PropertyGroup>
如何摆脱元素上的命名空间声明?
您需要为添加到 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);
如果您不对任何元素这样做(或者如果您像这样使用InnerXml
),则该元素将获得可怕的空命名空间。
发生这种情况的原因是您已通过在根节点上定义命名空间,将文档的默认命名空间定义为“ http://schemas.microsoft.com/developer/msbuild/2003 ”:
xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
然后继续向文档添加一个没有命名空间(“空”命名空间)的元素。 这必须有合格
xmlns=""
因为如果不是,则意味着新元素在前面提到的 Microsoft 命名空间中 - 它不是(或者更确切地说 - 你没有要求它)。
所以要么:
您实际上希望新元素位于 Microsoft 命名空间中 - 在这种情况下,您需要这么说。 最简单的方法是使用 createElement 并提供命名空间,尽管您可以使用 InnerXml 上的 xmlns 属性显式声明它(这不是一种特别好的添加节点的方法)。
您确实希望此元素位于空命名空间中,在这种情况下,您最好使用命名空间前缀来限定不在空命名空间中的所有其他节点。
我怀疑你想要前者。
可以在此处找到有关命名空间的快速概览。
为了避免在新创建的元素中出现额外的xmlns=""
属性,您可以将根命名空间作为参数传递:
$child = $doc.CreateElement("value", $doc.DocumentElement.NamespaceURI);
$res = $doc.PropertyGroup.AppendChild($child); # res here to avoid extra output
这将导致
<PropertyGroup>
<value></value>
</PropertyGroup>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.