从XElement中删除属性

本文关键字:属性 删除 XElement | 更新日期: 2023-09-27 18:01:31

我试图从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();

EDIT2:现在我已经尝试通过逐行和替换字符串来实现相同的目标。什么也没发生!!文档还是一样的。如果有人有类似的问题,请帮助我。

从XElement中删除属性

我已经找到了实际的问题所在。每次我在文档中更改某些内容时,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();
            }
        }

希望对你有帮助。

编辑:不创建新对象,创建一个只读对象,但它引用了一个交互对象