【问题标题】:Delete Attribute of Xml node c#删除xml节点c#的属性
【发布时间】:2020-08-04 18:49:00
【问题描述】:

我有一个这样的 XML 文件:

<?xml version="1.0" encoding="utf-8"?>
<ApplicationConfiguration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ua="http://opcfoundation.org/UA/2008/02/Types.xsd" xmlns="http://opcfoundation.org/UA/SDK/Configuration.xsd">
  <ServerConfiguration>
    <SecurityPolicies>
      <ServerSecurityPolicy>
        <SecurityMode>None_1</SecurityMode>
      </ServerSecurityPolicy>
    </SecurityPolicies>
  </ServerConfiguration>
</ApplicationConfiguration>

我想要的是通过代码添加更多名为 ServerSecurityPolicy 的节点。 然后我使用这段代码:

            string docaddress = "D:\\abc.xml";
            XDocument doc = XDocument.Load(docaddress);
            var root = doc.Root;
            var these = root.Descendants().Where(p => p.Name.LocalName == "SecurityPolicies");
            XElement addelement = new XElement("ServerSecurityPolicy");
            addelement.Add(new XElement("SecurityMode", "None_1"));           
            foreach (var elem in these)
            {
                elem.Add(addelement);
            }
            doc.Save(docaddress);

它确实可以,但是新添加的节点是这样的:

      <ServerSecurityPolicy xmlns="">
        <SecurityMode>None_1</SecurityMode>
      </ServerSecurityPolicy>

我不想要属性“xmlns”,然后我尝试通过以下方式删除它:

            var these2 = root.Descendants().Where(p => p.Name.LocalName == "ServerSecurityPolicy");
            foreach (var elem in these2)
            {
                    label2.Text += elem.Attribute("xmlns").Name.LocalName;
                    elem.Attribute("xmlns").Remove();
            }

label2.Text 显示“xmlnsxmlnsxmlsn...”,因此我认为 elem.Attribute("xmlns") 已指向我要删除的属性,但 Remove() 不起作用。 你能建议我一些方法来删除属性或添加没有属性的节点吗?
谢谢

【问题讨论】:

  • 欢迎来到 Stack Overflow。您的示例代码无法编译,并且已将其更改为 elem.Add(addelement); 以便它编译,新节点确实xmlns="" in - 使用 XML您向我们展示的文件。我怀疑这是因为您只向我们展示了文档的 part 部分,而您省略的部分设置了根名称空间。如果你能提供minimal reproducible example,帮助你会容易很多。
  • 您好 Jon Skeet,感谢您的回复。首先,你是对的,我将 XElement 命名为“ro”,但是当在这里发布线程时,我认为我应该使用更容易观察的东西,但我忘记更改最后一行。其次,由于xml文件很长,所以我只关注一些节点来缩短和简化问题,但从你的回答来看,错误似乎在其他地方。你能帮我检查一下完整的xml文件吗?
  • 不,请不要只将其放在云端硬盘上 - 请在问题中提供minimal reproducible example。 (Stack Overflow 的目的是创建一个高质量问题和答案的存储库。将来查看您的问题的其他人应该能够理解您的问题是否与他们的问题相关。)我们不需要 actual 完整文档 - 但我们确实需要 完整文档来演示问题,以及重现问题的代码。请编辑问题以修复代码(理想情况下将其变成一个可以复制/粘贴的真正完整的控制台应用程序)和文档。
  • 您好 Jon Skeet,感谢您指定我如何使用 Stack Overflow。我不确定控制台应用程序,但我已经按照我的理解编辑了我的问题(并检查了代码)。你能帮我重新检查一下我的问题吗?更多细节,正如你之前所说,我已经检查了根,我认为它的那些属性()创建了我的新节点的 xmlns 属性。

标签: c# linq-to-xml


【解决方案1】:

你得到一个空属性的原因——xmlns="" 指的是——是因为你的文档的根节点属于命名空间xsi。当您添加一个没有命名空间的节点时 - 正如您在示例中所做的那样 - 您实际上并没有将其绑定到 xsi 命名空间。

要使您的节点成为根命名空间的一部分,请替换

new XElement("ServerSecurityPolicy")

new XElement("ServerSecurityPolicy",
              new XAttribute(XNamespace.Xmlns + "xsi", "http://www.w3.org/2001/XMLSchema-instance"))

【讨论】:

  • 嗨@silkfire,我不确定命名空间,但我认为我的根节点共享2 个命名空间(xsiua),对吧?所以我尝试为ua 命名空间添加另一个XAttribute。问题是,新创建的节点现在有 3 个不同的属性,xsiua 与根节点相同,xmlns=""(空属性)。我做错什么了吗?
  • @halaMurak:不,这是关于 default 命名空间的,即http://opcfoundation.org/UA/SDK/Configuration.xsd
  • 文档属于别名为 xsi 的命名空间。它属于 http://opcfoundation.org/UA/SDK/Configuration.xsd 命名空间。 OP 应该在该命名空间中创建一个新元素 - 无需手动创建 xmlns 属性作为其中的一部分。 (基本上看我的回答。)
【解决方案2】:

问题是你要创建的元素实际上是在http://opcfoundation.org/UA/SDK/Configuration.xsd命名空间中,因为这部分根元素是文档的默认值:

xmlns="http://opcfoundation.org/UA/SDK/Configuration.xsd"

您可以轻松地在该命名空间中创建一个元素:

XNamespace configNs = "http://opcfoundation.org/UA/SDK/Configuration.xsd";
var these = root.Descendants(configNs + "ServerSecurityPolicy");

当您将 that 添加到文档时,您会发现它不会添加 xmlns="" 部分,因为您添加了一个没有命名空间的元素。

我还建议使用命名空间来查找元素:

XNamespace configNs = "http://opcfoundation.org/UA/SDK/Configuration.xsd";
var these = root.Descendants(configNs + "SecurityPolicies");

在我看来,这比只使用本地名称要干净得多。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-22
    • 2016-11-13
    • 1970-01-01
    相关资源
    最近更新 更多