从XElement中删除属性

我试图从xml文档中删除一些属性。 这是我尝试过的:

private void RemoveEmptyNamespace(XElement element) { foreach (XElement el in element.Elements()) { if (el.Attribute("xmlns") != null && el.Attribute("xmlns").Value == string.Empty) el.Attribute("xmlns").Remove(); if (el.HasElements) RemoveEmptyNamespace(el); } } 

但它不起作用。 当我在方法内部调试时,属性被删除,但是当方法完全执行时,没有保存任何更改。 该文件是一样的。 我想这是因为foreach循环,但我没有看到其他循环方式。

任何建议表示赞赏。

编辑:这是我正在使用的整个代码:

  var file = new FileStream(destinationPath, FileMode.Open); var doc = new XDocument(); doc = XDocument.Load(savedFile); RemoveEmptyNamespace(doc.Root);//method above file.SetLength(0); doc.Save(file); file.Close(); 

编辑2:现在我试图通过逐行和替换字符串来实现相同的目标。 什么都没发生! 该文件仍然是相同的。 如果有人有类似的问题,请帮助我。

我发现了实际问题是什么。 每次我在文档中更改内容时,XDocument类都会添加空白xmlns! 这就是为什么我无法删除它们。 它的行为与此类似,因为它需要为您创建的每个XElement定义命名空间。 所以我通过这样做解决了这个问题。 唯一需要做的是将名称空间添加到XElement名称。 像这样的东西:

 XNamespace nameSpace = "http://schemas.microsoft.com/developer/msbuild/2003"; var subType = new XElement(nameSpace + "SubType"); // strange but true 

我希望这能帮助有同样问题的人。 谢谢大家的回答。

这项工作对我来说:

 private static void RemoveEmptyNamespace(XElement element) { XAttribute attr = element.Attribute("xmlns"); if (attr != null && string.IsNullOrEmpty(attr.Value)) attr.Remove(); foreach (XElement el in element.Elements()) RemoveEmptyNamespace(el); } 

唯一的区别是我也在使用根元素中的xmlns属性。 但它确实有效,相信我

整体测试:

 class Program { static void Main(string[] args) { var x = new XElement("root", new XElement("t", new XAttribute("xmlns", "")), new XAttribute("aaab", "bb")); Console.WriteLine(x); RemoveEmptyNamespace(x); Console.WriteLine(x); } private static void RemoveEmptyNamespace(XElement element) { XAttribute attr = element.Attribute("xmlns"); if (attr != null && string.IsNullOrEmpty(attr.Value)) attr.Remove(); foreach (XElement el in element.Elements()) RemoveEmptyNamespace(el); } } 

从方法返回XElement并将其返回给变量,或作为引用传递

 private XElement RemoveEmptyNamespace(XElement element) { foreach (XElement el in element.Elements()) { if (el.Attribute("xmlns") != null && el.Attribute("xmlns").Value == string.Empty) el.Attribute("xmlns").Remove(); if (el.HasElements) el = RemoveEmptyNamespace(el); } return element; } 
  string xml = File.ReadAllText(@"C:\xml.txt"); XDocument wapProvisioningDoc = XDocument.Parse(xml); foreach(var ele in wapProvisioningDoc.Elements().Elements("characteristic"))//characteristic { var attribute = ele.Attribute("target"); if (attribute != null && !string.IsNullOrEmpty(attribute.Value)) { attribute.Remove(); } } 

问题是您正在从“foreach”循环中创建的只读对象中删除该属性。 您必须从“elements”中删除实例子项,而不是从“el”中删除。

我认为更好和更简单的选择是使用“for”来完成这项任务。 在C#中可能是这样的:

 for (int i = 0; i < element.ChildNodes.Count; i++) { if (element.ChildNodes[i].Attributes["xmlns"] != null && element.ChildNodes[i].Attributes["xmlns"].Value == String.Empty) { element.ChildNodes[i].Attributes.RemoveNamedItem("xmlns"); } if (element.ChildNodes[i].HasChildNodes) { element.ChildNodes[i].RemoveAll(); } } 

希望这可以帮助。

编辑:不要创建新对象,创建只读对象,但它引用交互对象。