修改 XML 文件

要使用 XDocument 修改 XML 文件,可以将文件加载到 XDocument 类型的变量中,在内存中修改它,然后保存它,覆盖原始文件。一个常见的错误是修改内存中的 XML 并期望磁盘上的文件发生变化。

给定一个 XML 文件:

<?xml version="1.0" encoding="utf-8"?>
<FruitBasket xmlns="http://www.fruitauthority.fake">
  <Fruit>
    <FruitName>Banana</FruitName>
    <FruitColor>Yellow</FruitColor>
  </Fruit>
  <Fruit>
    <FruitName>Apple</FruitName>
    <FruitColor>Red</FruitColor>
  </Fruit>
</FruitBasket>

你想将香蕉的颜色修改为棕色:

  1. 我们需要知道磁盘上文件的路径。
  2. XDocument.Load 的一个重载接收 URI(文件路径)。
  3. 由于 xml 文件使用命名空间,因此我们必须使用命名空间 AND 元素名称进行查询。
  4. 使用 C#6 语法的 Linq 查询以适应空值的可能性。如果条件没有找到任何元素,则此查询中使用的每个 . 都有可能返回空集。在 C#6 之前,你将分多步执行此操作,并在此过程中检查 null。结果是含有香蕉的 <Fruit> 元素。实际上是一个 IEnumerable<XElement>,这就是下一步使用 FirstOfDefault() 的原因。
  5. 现在我们从刚刚找到的 Fruit 元素中提取 FruitColor 元素。在这里我们假设只有一个,或者我们只关心第一个。
  6. 如果它不为 null,我们将 FruitColor 设置为 Brown
  7. 最后,我们保存 XDocument,覆盖磁盘上的原始文件。
// 1.
string xmlFilePath = "c:\\users\\public\\fruit.xml";

// 2.
XDocument xdoc = XDocument.Load(xmlFilePath);

// 3.
XNamespace ns = "http://www.fruitauthority.fake";

//4. 
var elBanana = xdoc.Descendants()?.
    Elements(ns + "FruitName")?.
    Where(x => x.Value == "Banana")?.
    Ancestors(ns + "Fruit");

// 5.
var elColor = elBanana.Elements(ns + "FruitColor").FirstOrDefault();

// 6.
if (elColor != null)
{
    elColor.Value = "Brown";
}

// 7.
xdoc.Save(xmlFilePath);

该文件现在看起来像这样:

<?xml version="1.0" encoding="utf-8"?>
<FruitBasket xmlns="http://www.fruitauthority.fake">
  <Fruit>
    <FruitName>Banana</FruitName>
    <FruitColor>Brown</FruitColor>
  </Fruit>
  <Fruit>
    <FruitName>Apple</FruitName>
    <FruitColor>Red</FruitColor>
  </Fruit>
</FruitBasket>