由于RDL XML文件中使用了两个命名空间:
<Report xmlns="http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition" xmlns:rd="http://schemas.microsoft.com/SQLServer/reporting/reportdesigner">
一个默认命名空间:xmlns="http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition"
没有前缀的元素属于默认命名空间,如:<DataSets>,<DataSet Name="Data">,<DataField>item_no</DataField>,<TypeName>System.String</TypeName>等。
访问时要使用XmlNamespaceManager,给这个默认命名空间起个别名,如:def.
XmlNamespaceManager nsmgr = new XmlNamespaceManager(xmlDoc.NameTable);
nsmgr.AddNamespace("def", "http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition");
SelectSingleNode时,也要加上这个def,如:root.SelectSingleNode(string.Format("def:DataSet[@Name='{0}']", dataSetName), nsmgr);
与xeDataSet.SelectSingleNode(string.Format("def:Fields/def:Field[@Name='{0}']", parameterName), nsmgr);
-----------------
一个名为"rd"的命名空间:xmlns:rd="http://schemas.microsoft.com/SQLServer/reporting/reportdesigner"
目前只有一个元素在使用:<rd:TypeName>System.String</rd:TypeName>
-------------
防止子元素出现 xmlns="" 的情况。在创建每个元素时都要指定命名空间。
xmlDoc.CreateElement("TypeName", nspDef); 这个是默认命名空间的。
xmlDoc.CreateElement("rd", "TypeName", nspRd); 这个是rd命名空间的。
zzz
public static void UpDateClientLocalXml2(string rdlFilePath, string type, string dataSetName, string parameterName, string parameterType) { //2014.05.28-30 Qingl 加入 报表文件升级的处理 //测试追加已打开的报表文件rdl文件是否存在该节点字段 ,不存在则先追加 bool fieldIsFlag = true; //明细字段是否存在,false 代表不存在,true代表存在 if (string.IsNullOrEmpty(dataSetName)) dataSetName = "Data"; #region 方法2 //1.加载rdl的xml文件 XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(rdlFilePath); //<Report xmlns="http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition" //xmlns:rd="http://schemas.microsoft.com/SQLServer/reporting/reportdesigner"> //2.默认命名空间 XmlNamespaceManager nsmgr = new XmlNamespaceManager(xmlDoc.NameTable); nsmgr.AddNamespace("def", "http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition"); string nspDef = "http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition"; string nspRd = "http://schemas.microsoft.com/SQLServer/reporting/reportdesigner"; if (type == "Fields") { //["DataSets"]["DataSet"]["Fields"] XmlElement root = xmlDoc.DocumentElement["DataSets"]; XmlElement xeDataSet = (XmlElement)root.SelectSingleNode(string.Format("def:DataSet[@Name='{0}']", dataSetName), nsmgr); if (xeDataSet == null) { /* <DataSet Name="DataM"> <Query> <DataSourceName> </DataSourceName> <CommandText> </CommandText> </Query> <Fields> <Field Name="zz"> <DataField>zz</DataField> <TypeName>System.String</TypeName> </Field> </Fields> </DataSet> */ XmlElement xenDataSet = xmlDoc.CreateElement("DataSet", nspDef); xenDataSet.SetAttribute("Name",dataSetName); XmlElement xenQuery = xmlDoc.CreateElement("Query", nspDef); XmlElement xenDataSourceName = xmlDoc.CreateElement("DataSourceName", nspDef); XmlElement xenCommandText = xmlDoc.CreateElement("CommandText", nspDef); xenQuery.AppendChild(xenDataSourceName); xenQuery.AppendChild(xenCommandText); XmlElement xenFields = xmlDoc.CreateElement("Fields", nspDef); XmlElement xenField = xmlDoc.CreateElement("Field", nspDef); xenField.SetAttribute("Name", parameterName); XmlElement xenDataField = xmlDoc.CreateElement("DataField", nspDef); xenDataField.InnerXml = parameterName; XmlElement xenTypeName = null; if (dataSetName == "Data") xenTypeName = xmlDoc.CreateElement("rd", "TypeName", nspRd); //名为"Data"的数据集用的是有前缀的命名空间 else xenTypeName = xmlDoc.CreateElement("TypeName", nspDef); xenTypeName.InnerXml = parameterType;//"System.String"; xenField.AppendChild(xenDataField); xenField.AppendChild(xenTypeName); xenFields.AppendChild(xenField); xenDataSet.AppendChild(xenQuery); xenDataSet.AppendChild(xenFields); root.AppendChild(xenDataSet); } else { XmlElement xeFields = (XmlElement)xeDataSet.SelectSingleNode(string.Format("def:Fields"), nsmgr); XmlElement book1 = (XmlElement)xeFields.SelectSingleNode(string.Format("def:Field[@Name='{0}']", parameterName), nsmgr); //DataSet Field 部分的处理 if (book1 == null) { book1 = xmlDoc.CreateElement("Field", nspDef); book1.SetAttribute("Name", parameterName); XmlElement objNodeChild = xmlDoc.CreateElement("DataField", nspDef); objNodeChild.InnerXml = parameterName; book1.AppendChild(objNodeChild); XmlElement objNodeChildTypeName = null; if (dataSetName == "Data") objNodeChildTypeName = xmlDoc.CreateElement("rd", "TypeName", nspRd); //名为"Data"的数据集用的是有前缀的命名空间 else objNodeChildTypeName = xmlDoc.CreateElement("TypeName", nspDef); objNodeChildTypeName.InnerXml = parameterType;//"System.String"; book1.AppendChild(objNodeChildTypeName); xeFields.AppendChild(book1); } } } //4.保存文件 xmlDoc.Save(rdlFilePath); #endregion }
zzz