改变现有xml属性值的值,没有LINQ,C#

时间:2018-01-23 18:25:22

标签: c# xml

我想使用C#更改现有属性值的值。

我似乎无法在谷歌上找到答案,可能是因为我不太了解术语,不能明智地提出这个问题。

我可以找到:

  • 很多编写 xml doc的方法,包含新元素\ attributes
  • 读取现有元素属性值的方法

但我无法深入了解 已存在的 元素的属性并更改该属性的值。

要提供上下文,假设这是位于 C:\ stuff.xml 的名为“stuff.xml”的xml文件:

<?xml version="1.0" encoding="utf-8"

<configuration>
    <add key="apple" 
         value="red"/>
    <add key="school_bus" 
         value="yellow"/>
    <add key="grass" 
         value="orange"/>
    <system.Net>
          <binding>
                <endpoint address="https://1111.11.11.11:7276/Service"
                          binding="basicHttpBinding"/>
                 <endpoint address="http://localhost/Service"
                           binding="advancedHttpBinding"/>
           </binding>
</configuration>

我想做的事情 - 不使用LINQ - 是将草的颜色值更改为“绿色”,并将第一个端点的地址更改为https://222.22.22.22:7276/Service

(我没有嫁给不使用LINQ,只是作为非LINQ用户,我发现它是不可读的。)

我确信有办法做到这一点! (它很容易找到 - 我找不到它。)

我想答案将使用 XmlWriter 对象,只是我不知道如何向下钻取到子元素而然后使用XmlWriter对象

@maccettura:你的可疑头脑是正确的......有点儿。它是一个配置文件,但它不是app.config文件。它必须改变。嗯...序列化。好。我有点看过那个,但我一直认为序列化基本上是把整个文件的值读成一个对象,那么你可以用它做什么你会...我会调查它。谢谢。

3 个答案:

答案 0 :(得分:3)

应该使用LINQ to XML,因为它几乎非常简单:

var xml = XDocument.Parse(@"C:\stuff.xml");

xml.XPathSelectElement("configuration/add[@key='grass']")
  ?.SetAttributeValue("value", "green")

xml.XPathSelectElement("configuration/system.Net/binding/endpoint[@address='https://1111.11.11.11:7276/Service']")
  ?.SetAttributeValue("address", "https://222.22.22.22:7276/Service")

或者,如果您不喜欢XPath语法:

xml.Root
   .Elements("add")
   .Where(o => (string)o.Attribute("key") == "grass")
   .FirstOrDefault()
  ?.SetAttributeValue("color", "green");

xml.Root
   .Element("system.Net")
  ?.Element("binding")
  ?.Elements("endpoint")
   .FirstOrDefault(o => (string)o.Attribute("address") == "https://1111.11.11.11:7276/Service")
  ?.SetAttributeValue("address", "https://222.22.22.22:7276/Service")

无论哪种方式,保存文件都很简单:

xml.Save(@"C:\stuff.xml")

答案 1 :(得分:1)

查看对此问题的回复,查找使用XmlDocument的答案,因为您不想使用LINQ。 How to change XML Attribute

答案 2 :(得分:0)

您可以将xml文件序列化,读取和反序列化为代码中的对象。

        YourObjectClass yourObjectName = new YourObjectClass();

        try
        {
            XmlSerializer serializer = new XmlSerializer(typeof(YourObjectClass));

            using (TextReader reader = new StreamReader(locationString))
            {
               yourObjectName = (YourObjectClass)serializer.Deserialize(reader);
            }
        }
        catch (Exception ex)
        {
            //do whatever you need to with caught exceptions here.
        }

你的班级将会是这样的:

[Serializable]
public class YourObjectClass
{
    public string StringValue1 { get; set; }

    public string StringValue2{ get; set; }

    [XmlElement("YourOtherObjectClass")]
    public List<YourOtherObjectClass> OtherObjectClassList = new List<YourOtherObjectClass>();
}

[Serializable]
public class YourOtherObjectClass
{
    public string StringValue1 { get; set; }
}

您将需要:

using System.Xml.Serialization;

这实际上是将xml引入代码的最简单方法。如果你真的尝试,你可以做更少的线,但这是短而干净的。然后,您可以在使用它们之前操作代码中的任何值以满足您的需要。

如评论中所述,如果您正在阅读配置,则可能不应在代码中对其进行编辑,然后将其保存。但是如果你有一些逻辑需要在不同的情况下使用不同的值,那么将你的xml反序列化为一个对象然后进行操作。这就是对象的用途。