我在LINQ中遇到了一些名称空间问题。因此,从MSDN's Tutorial开始,我们可以执行以下操作,使用LINQ将命名空间添加到XML文档:
// Create an XML tree in a namespace.
XNamespace aw = "http://www.adventure-works.com";
XElement root = new XElement(aw + "Root",
new XElement(aw + "Child", "child content")
);
Console.WriteLine(root);
这将为您提供XML:
<Root xmlns="http://www.adventure-works.com">
<Child>child content</Child>
</Root>
但我想做的是:
XNamespace aw = "http://www.adventure-works.com";
XElement root = new XElement(aw + "Roots");
XElement child = new XElement("Child", "child content");
root.Add(child);
Console.WriteLine(root);
但这给了我以下xml:
<Root xmlns="http://www.adventure-works.com">
<Child xmlns="">child content</Child>
</Root>
问题是我不希望我的子元素中的xmlns=""
(编辑:我不希望我的子元素中有任何名称空间),我希望它看起来只是就像第一种方式产生它一样。我正在构建一个相当大的XML文件,因此我无法在同一声明中添加所有元素,并且需要能够使用仍具有多个Add
的{{1}}和SetAttributeValue
方法第一个元素上的XElements
。我有什么想法可以做到这一点吗?
谢谢!
答案 0 :(得分:6)
此行为是XML信息集的基础。 xmlns
声明的效果限定在所有子内容中;由于您没有为子元素指定命名空间,因此标准行为是将其放在未命名的命名空间中。为了将一个元素嵌套在一个声明默认命名空间的未命名命名空间内,需要xmlns=''
声明将默认命名空间重置为未命名。
总结一下,根据你的编辑:
xmlns=''
才能覆盖文档元素中声明的名称空间。xmlns=''
内容),则需要确保相同名称空间被添加到代码中的所有名称。我无法让XElement
自动继承其父级的命名空间。但是,在完成构建DOM之后,您可以随时对其进行后处理,以便在任何地方设置一个名称空间,类似于:
foreach(var element in doc.Descendants())
element.Name = aw + element.Name.LocalName;
我不相信这样做除了一次性代码之外的其他任何东西都是可取的,因为它可能会对可维护性产生不利影响。我必须处理混合命名空间的许多XML文档,以及像上面的代码片段一样“粉碎”命名空间确实会破坏混合命名空间文档的语义。
答案 1 :(得分:0)
我能想到的唯一方法是在代码中构建整个文档,然后编写一个通用方法,将一个命名空间应用于所有元素。这可能很难做到正确,但肯定可能。
基本上new XElement("Child")
被记录为创建一个没有命名空间的元素 - 你无法改变它。
另一种选择是将所有元素名称提取到变量中(可能是本地或静态只读)并在那里应用命名空间 :
private static readonly XNamespace AdventureWorksNs = "http://www....";
private static readonly XName RootName = AdventureWorksNs + "Root";
private static readonly XName ChildName = AdventureWorksNs + "Child";
然后
XElement root = new XElement(RootName,
new XElement(ChildName, "child content")
);