C# Linq XDoc - 添加同名元素

C# Linq XDoc - add element with same name

我正在尝试使用 c# Linq XDocument 编写一个小 XML 文件。

最终的 xml 文件应该如下所示:

<?xml version="1.0" encoding="utf-8"?>
<Root>
  <Asset InternalID="SOMEID" LastSaveDate="2016-10-28" LastSaveTime="01:01:33:00" AssetType="New">
    <type_metadata>
      <FIELD name="filename">SOMEID.MOV</FIELD>
      <FIELD name="duration">00:00:00:10</FIELD>
    </type_metadata>
  </Asset>
</Root>

这是我的代码:

XDocument doc = new XDocument(new XDeclaration("1.0", "UTF-8", null));
doc.Add(new XElement("Root"));
doc.Element("Root").Add(new XElement("Asset"));
doc.Element("Root").Element("Asset").Add(new XAttribute("InternalID", a.InternalID));
doc.Element("Root").Element("Asset").Add(new XAttribute("LastSaveDate", a.lastSaveDate));
doc.Element("Root").Element("Asset").Add(new XAttribute("LastSaveTime", a.lastSaveTime));
doc.Element("Root").Element("Asset").Add(new XAttribute("AssetType", a.AssetType));
doc.Element("Root").Element("Asset").Add(new XElement("type_metadata"));

doc.Element("Root").Element("Asset").Element("type_metadata").Add(new XElement("FIELD"));
doc.Element("Root").Element("Asset").Element("type_metadata").Element("FIELD").Add(new XAttribute("name","filename"));
doc.Element("Root").Element("Asset").Element("type_metadata").Element("FIELD").Value = a.filename;

doc.Element("Root").Element("Asset").Element("type_metadata").Add(new XElement("FIELD"));
doc.Element("Root").Element("Asset").Element("type_metadata").Element("FIELD").Add(new XAttribute("name", "duration"));
doc.Element("Root").Element("Asset").Element("type_metadata").Element("FIELD").Value = a.duration;

一切正常,直到我尝试放入第二个 "FIELD" 元素。 这样做的正确方法是什么?我做了一些研究,但找不到与我要完成的目标直接相关的简单答案。

如果在将新的 FIELD 元素添加到父元素之前准备好它会更容易:

var filename = new XElement("FIELD",
                    new XAttribute("name","filename"),
                    a.filename
               );
var duration = new XElement("FIELD",
                    new XAttribute("name","duration"),
                    a.duration
               );
doc.Element("Root").Element("Asset").Element("type_metadata").Add(field);
doc.Element("Root").Element("Asset").Element("type_metadata").Add(duration);

那是因为当您尝试添加第二个元素时,您使用的是:

doc.Element("Root").Element("Asset").Element("type_metadata").Element("FIELD")

它会return第一个匹配名字的元素,本例是之前添加的"FIELD"元素,已经有"name"属性。

我建议您先创建元素本身,然后再将其附加到文档。这样您就不必一遍又一遍地搜索元素了:

XDocument doc = new XDocument(new XDeclaration("1.0", "UTF-8", null));

var root = new XElement("Root");

var asset = new XElement("Asset");
asset.Add(new XAttribute("InternalID", a.InternalID));
asset.Add(new XAttribute("LastSaveDate", a.lastSaveDate));
asset.Add(new XAttribute("LastSaveTime", a.lastSaveTime));
asset.Add(new XAttribute("AssetType", a.AssetType));

var type_metadata = new XElement("type_metadata");

var field = new XElement("FIELD");
field.Add(new XAttribute("name","filename"));
field.Value = a.filename;

type_metadata.Add(field);

var field2 = new XElement("FIELD");
field2.Add(new XAttribute("name","duration"));
field2.Value = a.duration;

type_metadata.Add(field2);

asset.Add(type_metadata);

root.Add(asset);

doc.Add(root);

此外,您可以在一条语句中创建整个文档:

XDocument doc = new XDocument(
    new XDeclaration("1.0", "UTF-8", null),
    new XElement("Root",
        new XElement("Asset",
            new XAttribute("InternalID", a.InternalID),
            new XAttribute("LastSaveDate", a.lastSaveDate),
            new XAttribute("LastSaveTime", a.lastSaveTime),
            new XAttribute("AssetType", a.AssetType),
            new Element("type_metadata",
                new XElement("FIELD",
                    new XAttribute("name", "filename"),
                    a.filename),
                new XElement("FIELD",
                    new XAttribute("name", "duration"),
                    a.duration)))));

这可以通过不同的方式实现。我只是按照你的方法。由于您有多个 FIELD 元素,因此您的代码需要稍作修改。以下代码将按预期工作。

XDocument doc = new XDocument(new XDeclaration("1.0", "UTF-8", null));
doc.Add(new XElement("Root"));
doc.Element("Root").Add(new XElement("Asset"));
doc.Element("Root").Element("Asset").Add(new XAttribute("InternalID", "intID"));
doc.Element("Root").Element("Asset").Add(new XAttribute("LastSaveDate", "28.10.2016"));
doc.Element("Root").Element("Asset").Add(new XAttribute("LastSaveTime", "1.48PM"));
doc.Element("Root").Element("Asset").Add(new XAttribute("AssetType", "Laptop"));
doc.Element("Root").Element("Asset").Add(new XElement("type_metadata"));

doc.Element("Root").Element("Asset").Element("type_metadata").Add(new XElement("FIELD"));
doc.Element("Root").Element("Asset").Element("type_metadata").Element("FIELD").Add(new XAttribute("name", "filename"));
doc.Element("Root").Element("Asset").Element("type_metadata").Element("FIELD").Value = "a.txr";

doc.Element("Root").Element("Asset").Element("type_metadata").Add(new XElement("FIELD"));
doc.Element("Root").Element("Asset").Element("type_metadata").Elements().Last().Add(new XAttribute("name", "duration"));
doc.Element("Root").Element("Asset").Element("type_metadata").Elements().Last().Value = "00:12:98";