将 xmlns 属性添加到根元素
Posted
技术标签:
【中文标题】将 xmlns 属性添加到根元素【英文标题】:Add xmlns attribute to root element 【发布时间】:2012-05-12 07:45:59 【问题描述】:我有 C# 程序来生成 RDL 文件,以便在报告服务中显示报告。 我使用 Linq to Xml 生成 Xml。
当我尝试将 xmlns XAttribute 添加到报表元素时,我遇到了几个问题。
我测试了以下方法:
第一:
XDocument d = new XDocument(
new XDeclaration("1.0", "utf-8", "yes"),
new XElement("Report",
new XAttribute(XNamespace.Xmlns + "rd", "http://schemas.microsoft.com/SQLServer/reporting/reportdesigner"),
new XAttribute(XNamespace.Xmlns + "cl", "http://schemas.microsoft.com/sqlserver/reporting/2010/01/componentdefinition"),
new XAttribute("xmlns", "http://schemas.microsoft.com/sqlserver/reporting/2010/01/reportdefinition"),
new XElement("DataSources", ""),
new XElement("DataSets", ""),
new XElement("ReportSections",
这是我的代码的一部分,展示了如何生成 xml:
秒:
XNamespace reportDef = "http://schemas.microsoft.com/sqlserver/reporting/2010/01/reportdefinition";
XDocument d = new XDocument(
new XDeclaration("1.0", "utf-8", "yes"),
new XElement(reportDef + "Report",
new XAttribute(XNamespace.Xmlns + "rd", "http://schemas.microsoft.com/SQLServer/reporting/reportdesigner"),
new XAttribute(XNamespace.Xmlns + "cl", "http://schemas.microsoft.com/sqlserver/reporting/2010/01/componentdefinition"),
new XElement("DataSources", ""),
new XElement("DataSets", ""),
new XElement("ReportSections",...
第一种方法返回一个错误,第二种方法将属性 xmlns 添加到所有子节点。
我想要这种格式:
<Report xmlns="http://schemas.microsoft.com/sqlserver/reporting/2010/01/reportdefinition">
【问题讨论】:
【参考方案1】:尝试使用XNamespace
添加子节点,如How to: Create a Document with Namespaces (C#) (LINQ to XML) 中所述
XNamespace reportDef = "http://schemas.microsoft.com/sqlserver/reporting/2010/01/reportdefinition";
XElement root = new XElement(reportDef + "Report",
new XElement(reportDef + "Child", "child content"));
这应该会给你想要的结果。
您还可以通过添加xmlns
属性来添加默认命名空间
XElement xe = new XElement(reportDef + "Report",
new XAttribute("xmlns", "http://schemas.microsoft.com/sqlserver/reporting/2010/01/reportdefinition"),
new XElement(reportDef + "Child", "child content"));
【讨论】:
我使用这个解决方案,但不幸的是,这个属性像以前一样添加到所有子节点。 看起来很奇怪,因为我无法重现它。尝试像我的第二个示例一样添加默认命名空间属性。也许更新您的问题并显示更多您的实际代码。 如果你有这样的例子,请发给我。【参考方案2】:您可以从@Filburt 的回答和this 帖子中看到,xmlns 属性是一个特殊属性。只能通过 XNamespace 类访问。
下面我将给你一个关于如何创建命名空间的例子。您应该查看How to: Create a Document with Namespaces 了解更多信息。您的代码向所有子节点添加 xmlns 标记的原因是因为您没有在同一命名空间中创建所有子节点。
-
要将元素放入默认命名空间,请创建
XNamespace
(请参阅下面的ns1)并将值添加到元素名称之前。例如:new XElement(ns1 + "Report");
这会在 ns1 命名空间中创建一个元素 <Report>
,并且没有前缀。
要添加其他命名空间,请添加带有命名空间和前缀的属性。例如,new XAttribute(XNamespace.Xmlns + "ns2", ns2)
将命名空间添加到具有 ns2
前缀的 <Report>
元素。此后,每次使用 ns2 命名空间创建元素 (new XElement(ns2+"DataSources")
) 时,都会使用前缀。前缀可以用在具有前缀声明的元素下面的所有后代中。这是你犯错的地方。
StringBuilder sb = new StringBuilder();
XmlWriterSettings xws = new XmlWriterSettings();
xws.OmitXmlDeclaration = true;
xws.Indent = true;
using (XmlWriter xw = XmlWriter.Create(sb, xws))
XNamespace ns1 = "http://schemas.microsoft.com/sqlserver/reporting/2010/01/reportdefinition";
XNamespace ns2 = "http://schemas.microsoft.com/SQLServer/reporting/reportdesigner";
XNamespace ns3 = "http://schemas.microsoft.com/sqlserver/reporting/2010/01/componentdefinition";
XDocument doc = new XDocument(new XDeclaration("1.0", "utf-8", "yes"));
XElement reportElement = new XElement(ns1 + "Report",
new XAttribute(XNamespace.Xmlns + "ns2", ns2),
new XAttribute(XNamespace.Xmlns + "ns3", ns3));
doc.Add(reportElement);
reportElement.Add(new XElement(ns2+"DataSources"));
reportElement.Add(new XElement(ns3+"DataSets"));
reportElement.Add(new XElement(ns1+"ReportSections"));
doc.WriteTo(xw);
System.Diagnostics.Debug.Write(sb.ToString());
【讨论】:
是的,所有子节点都以相同的方式创建。我编辑第一个和第二个示例代码。请检查一下。谢谢 @AmirReza 我添加了一个示例并指出了您的错误。基本上,您需要输入new XElement(reportDef+"DataSources", "")
而不是new XElement("DataSources", "")
。子项中缺少名称空间,因此它们最终会出现在空名称空间中。以上是关于将 xmlns 属性添加到根元素的主要内容,如果未能解决你的问题,请参考以下文章
为啥 XContainer.Add 方法无论如何都会向添加的元素添加“xmlns”属性,我该如何阻止这种行为?
如果元素具有 xmlns 属性,Xpath 将失败 [重复]