3

我正在尝试通过元素的属性对 LINQ 中的 XML 文件中的元素进行排序:

public void SortXml()
{
    XDocument doc = XDocument.Load(filename);
    XDocument datatemp = new XDocument(doc);

    doc.Descendants("Thing").Remove();
    var module = datatemp.Descendants("Thing").OrderBy(x => 
        (int)int.Parse(x.Attribute("ID").Value));
    doc.Element("Thing").Add(module);

    doc.Save(filename);
}

XML:

<Entry>
  <Properties>
    <Thungs Count="2">
      <Thing ID="1">
        <thing1 num="8" />
        <thing1 num="16" />
      </Thing>
      <Thing ID="31">
        <thing1 num="8" />
        <thing1 num="16" />
      </Thing>
    </Thungs>
  </Properties>
</Entry>

但在这条线上,doc.Element("Thing").Add(module);我得到了一个NullReferenceException. 怎么了?

4

3 回答 3

4

doc.Element("Thing")将返回null,因为没有元素被调用"Thing"doc.Descendants("Thing").Remove();调用已将它们全部删除。即使没有,XElement'Element方法也不会查看间接后代,因此您需要提供正确的元素名称链,指向您要修改的元素。

你的意思是写

doc.Element("Entry").Element("Properties").Element("Thungs").Add(module);
于 2012-07-08T10:09:57.570 回答
1

如果您要简化它,为什么不一路走下去呢?

XDocument doc = XDocument.Load(filename);
var ordered = doc.Descendants("Thing")
                 .OrderBy(thing => thing.Attribute("ID").Value)
                 .ToList(); // force evaluation
doc.Descendants("Thing").Remove();
doc.Descendants("Thungs").Single().Add(ordered);
doc.Save(filename);
于 2012-07-08T10:54:33.033 回答
0

你甚至不需要创建两个XDocument对象:

        XDocument doc = XDocument.Load(filename);

        var query = from things in doc.Descendants("Thing")
                    orderby things.Attribute("ID").Value
                    select things;

        var orderedThings = query.ToList<XElement>();
        doc.Descendants("Thing").Remove();
        doc.Descendants("Thungs").First().Add(orderedThings);

        doc.Save(filename);

编辑:如果您知道 XML 架构中的“路径”,最好使用 dasblinkenlight 建议使用:

    doc.Element("Entry").Element("Properties").Element("Thungs").Add(orderedThings);

而不是Descendants("Thungs").First()线。

于 2012-07-08T10:44:23.473 回答