将xmlns属性添加到根元素

时间:2012-05-12 07:45:59

标签: c# xml linq linq-to-xml xml-namespaces

我有C#程序生成RDL文件用于报告服务中的whitch Show报告。 我使用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",...

第一种方法返回Error,第二种方法将属性 xmlns 添加到所有子节点。

我想要这种格式:

<Report xmlns="http://schemas.microsoft.com/sqlserver/reporting/2010/01/reportdefinition">

2 个答案:

答案 0 :(得分:4)

尝试使用How to: Create a Document with Namespaces (C#) (LINQ to XML)

中所述的XNamespace添加子节点
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"));

答案 1 :(得分:1)

您可以从@ Filburt的回答和this帖子中看到,xmlns属性是一个特殊属性。它只能通过XNamespace类访问。

下面我将举例说明如何创建命名空间。您应该查看How to: Create a Document with Namespaces以获取更多信息。您的代码向所有子项添加 xmlns 标记的原因是您没有在同一名称空间中创建所有子节点。

  1. 要将元素放入默认命名空间,请创建XNamespace(请参阅下面的ns1)并将值添加到元素名称前面。例如:new XElement(ns1 + "Report");这会在ns1名称空间中创建一个元素<Report>,并且没有前缀。
  2. 要添加其他名称空间,请添加具有名称空间和前缀的属性。例如,new XAttribute(XNamespace.Xmlns + "ns2", ns2)<Report>元素添加了ns2前缀的命名空间。在此之后,每次使用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());