以下是我的代码片段。
FilterText = HttpUtility.UrlDecode(FilterTxt.Value.ToString());
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
TextWriter tw = new StreamWriter("D:\\FilterTest.rdl");
tw.WriteLine(FilterText);
tw.Close();
XmlDocument reportrdl = new XmlDocument();
reportrdl.Load(ReportFile);
NMS = reportrdl.NamespaceURI;
XmlNodeList fieldsnode = reportrdl.GetElementsByTagName("DataSet");
//XmlElement xoo = reportrdl.CreateElement("Filters", NMS);
//reportrdl.AppendChild(xoo);
foreach (XmlNode fields in fieldsnode)
{
// second document to merge (the new Filter File)
XmlDocument filterrdl = new XmlDocument();
filterrdl.Load("D:\\FilterTest.rdl");
XmlNode imported = reportrdl.ImportNode(filterrdl.DocumentElement, true);
fields.AppendChild(imported);
break;
}
//XmlNodeList filtersnode = reportrdl.GetElementsByTagName("Filters");
//foreach (XmlNode filters in filtersnode)
//{
// filters.Attributes.RemoveNamedItem("xmlns");
// }
reportrdl.Save("D:\\NewFilter.rdl");
以下是rdl文件的片段:
<Report xmlns="http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition" xmlns:rd="http://schemas.microsoft.com/SQLServer/reporting/reportdesigner">
<DataSources>
<DataSource Name="BOSS">
<rd:DataSourceID>c6a8409e-71a4-4e96-86ad-b300a5b942c3</rd:DataSourceID>
<ConnectionProperties>
<DataProvider>SQL</DataProvider>
<ConnectString>dats a no no</ConnectString>
<IntegratedSecurity>true</IntegratedSecurity>
</ConnectionProperties>
</DataSource>
</DataSources>
继<Query>
之后,我需要合并<Filters>
这是该文件:
<Filters>
<Filter>
<FilterExpression>=Fields!RoleID.Value</FilterExpression>
<Operator>Equal</Operator>
<FilterValues>
<FilterValue>=27</FilterValue>
</FilterValues>
</Filter>
</Filters>
结束<Filters xmlns="">
而不是<Filters>
由于
答案 0 :(得分:2)
您需要向我们展示您尝试合并的两个文件的XML样本。
可能发生的是,在第一个文件reportrdl中,DataSet
元素位于除“”之外的默认命名空间声明下。因此,它们下面没有名称空间前缀且不覆盖默认名称空间声明的每个元素都将位于其祖先声明的默认名称空间中。
但是您要导入不在该命名空间中的Filters
个元素,并且没有前缀。因此,为了防止它们继承不适用于它们的默认命名空间,他们需要取消声明默认命名空间,这是使用xmlns=""
完成的。
如果不是上述情况,请提供两份XML文件的样本,这样我们就不会在黑暗中做手术。
如果上面的 ,那么回答你的问题是为什么你不希望输出中有xmlns=""
吗?听起来这是正确的输出。 但也许你不想要它,因为你希望导入的Filters
元素与其父元素在同一个命名空间中;在这种情况下,您需要更改imported
的命名空间。然后命名空间声明将会跟随。
或者您可能希望导入的节点不在命名空间中,因此输出在技术上已经正确,但您不喜欢xmlns=""
的美学。或者可能由于某种原因,下游的XML消费者会因xmlns=""
而窒息。告诉我们有关您的约束的更多信息,以便我们知道如何提供帮助。
更新
好的,现在我们知道了
"http://schemas.microsoft.com/sqlserver/reporting/2009/01/reportdefinition"
。我们可以告诉你,因为顶级元素<Report>
上有默认的名称空间声明:xmlns="http://schemas.microsoft.com.../reportdefinition"
。这意味着对于<Report>
和所有后代,任何没有名称空间前缀的元素都被认为是在reportdefinition名称空间中。<Filters>
)应位于同一reportdefinition命名空间中。我从MS documentation推断出这一点,但目前尚不清楚。遗憾的是,大部分文档都很糟糕......甚至还有ill-formed XML!<Filters>
元素和后代实际上没有名称空间(在导入它们之前),因为它们没有名称空间前缀,也没有默认名称空间声明。因此,当您导入<Filters>
元素时,AppendChild()
必须将其保持在与其相同的命名空间(即没有命名空间)中 - 否则,就像更改其名称一样。无命名空间中的<Filters>
与<Filters>
命名空间中的reportdefinition
不同。如果<Filters>
按原样附加<DataSet>
,它将从其新祖先<Report>
继承默认命名空间声明,从而将其命名空间更改为reportdefinition命名空间。
但是,执行希望它位于reportdefinition命名空间中。最简单的方法是更改导入的文件,以便该命名空间中的<Filters>
已经:
<Filters xmlns="http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition">
<Filter>
然后,AppendChild()将看到<Filters>
已经在其新祖先的默认命名空间中,并且不必取消声明默认命名空间。实际上,它可以删除<Filters>
上的默认命名空间声明,现在这是多余的。
但是,我们无法保证它将删除它。理解XML命名空间的一个重要事项是,重要的是每个元素在中的命名空间。使用什么前缀来表示命名空间并不重要,也不重要声明命名空间前缀(或默认命名空间)的位置或次数:只要每个元素最终都在正确的命名空间。
因此,导入的<Filters>
元素是否最终具有默认命名空间声明(DND)或对于任何合法的XML使用者来说都不重要。重要的是它在reportdefinition命名空间中。如果Microsoft RDL处理器在DND上发生阻塞,则表示处理器不符合XML命名空间标准。
我真的建议阅读关于XML命名空间的简短教程......尽管它们声名远扬,但它们并不复杂;当你使用标准化的XML词汇表时,它们几乎无处不在;并了解声明如何工作可以为您节省很多麻烦。 This one's not short但这很好。我不能推荐w3schools,因为它会将前缀与命名空间混淆。 :-P
哇,好久不见。我觉得这是必要的:我们可以整天保释水,但我宁愿堵塞泄漏,这是因为不了解XML命名空间声明的工作原理。