使用 C# 删除 XML 中的默认命名空间属性 - 无法通过 ref 传递对象然后迭代
本文关键字:ref 迭代 然后 对象 XML 删除 属性 命名空间 默认 使用 | 更新日期: 2023-09-27 18:31:18
我目前正在处理一个有缺陷的代码,旨在从XML文档中剥离所有命名空间并将它们重新添加到标头中。我们之所以使用它,是因为我们摄取非常大的 xml 文档,然后在小片段中重新提供它们,因此每个项目都需要复制父文档中的命名空间。
XML 首先作为 XmlDocument 加载,然后传递给删除命名空间的函数:
_fullXml = new XmlDocument();
_fullXml.LoadXml(itemXml);
RemoveNamespaceAttributes(_fullXml.DocumentElement);
remove 函数循环访问整个文档,查找命名空间并删除它们。它看起来像这样:
private void RemoveNamespaceAttributes(XmlNode node){
if (node.Attributes != null)
{
for (int i = node.Attributes.Count - 1; i >= 0; i--)
{
if (node.Attributes[i].Name.Contains(':') || node.Attributes[i].Name == "xmlns")
node.Attributes.Remove(node.Attributes[i]);
}
}
foreach (XmlNode n in node.ChildNodes)
{
RemoveNamespaceAttributes(n);
}
}
但是,我发现它不起作用 - 它使所有命名空间保持不变。
如果使用调试器循环访问代码,那么它看起来正在执行它应该做的事情 - 节点对象删除了其命名空间属性。但原始_fullXml文件保持不变。我认为这是因为该函数正在查看传递给它的数据的克隆,而不是原始数据。
所以我的第一个想法是通过 ref 传递它。但我不能这样做,因为 foreach 循环中函数的迭代部分有一个编译错误 - 你不能通过引用传递对象 n。
第二个想法是传递整个_fullXml文档,但这也不起作用,猜测因为它仍然是一个克隆。
所以看起来我需要解决通过 ref 传递文档然后遍历节点以删除所有命名空间的问题。这显然需要重新设计此代码片段,但我看不到这样做的好方法。谁能帮忙?
干杯马 特
要剥离命名空间,可以像这样完成:
void StripNamespaces(XElement input, XElement output)
{
foreach (XElement child in input.Elements())
{
XElement clone = new XElement(child.Name.LocalName);
output.Add(clone);
StripNamespaces(child, clone);
}
foreach (XAttribute attr in input.Attributes())
{
try
{
output.Add(new XAttribute(attr.Name.LocalName, attr.Value));
}
catch (Exception e)
{
// Decide how to handle duplicate attributes
//if(e.Message.StartsWith("Duplicate attribute"))
//output.Add(new XAttribute(attr.Name.LocalName, attr.Value));
}
}
}
你可以这样称呼它:
XElement result = new XElement("root");
StripNamespaces(NamespaceXml, result);
我不是 100% 确定这没有失败的情况,但我想到你可以做到
string x = Regex.Replace(xml, @"(xmlns:?|xsi:?)(.*?)=""(.*?)""", "");
在原始 XML 上以摆脱命名空间。
这可能不是解决这个问题的最佳方法,但我想我会把它放在那里。