LINQ - 根据值删除元素

LINQ - Remove elements based on value

这是我的 XML 文件的样子:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!--QTabs Data Storage-->
<SyncTimes>
  <LastSyncTime>
    <id>1</id>
    <SyncTime>3/31/2015 2:03:28 PM</SyncTime>
  </LastSyncTime>
  <LastSyncTime>
    <id>2</id>
    <SyncTime>3/31/2015 2:14:24 PM</SyncTime>
  </LastSyncTime>
  <LastSyncTime>
    <id>3</id>
    <SyncTime>3/31/2015 2:14:25 PM</SyncTime>
  </LastSyncTime>
</SyncTimes>

我正在尝试创建一种删除旧同步时间的方法。这是我的尝试:

    public void deleteArchivedSyncs(int months)
    {
        var xElement = (from element in XMLDocObject.Elements("SyncTimes").Elements("LastSyncTime")
                        where Convert.ToDateTime(element.Attribute("SyncTime").Value) < DateTime.Now.AddHours(-months)
                        select element);
        xElement.Remove();
    }

目前我是运行方法用零来查看它是否运行。

这就是我得到的:

对我来说,这里似乎导致了空异常:

element.Attribute("SyncTime").Value

但我不明白基于 XML 为什么会发生这种情况。

<SyncTime> 不是属性 - 它是元素。因此表达式 element.Attribute("SyncTime") returns 为 null,并且试图访问 Value 会引发空引用异常。

使用 XmlSerializer,您可以将 xml 反序列化为类型

public class LastSyncTime
{
    public int id { get; set; }
    public string SyncTime { get; set; }
    [XmlIgnore]
    public DateTime Time  // This is used to convert DateTime to a string
    {
        get
        {
            DateTime result;
            DateTime.TryParse( SyncTime, out result );
            return result;
        }
        set
        {
            SyncTime = value.ToString();
        }
    }
}

[System.Xml.Serialization.XmlTypeAttribute( AnonymousType = true )]
[System.Xml.Serialization.XmlRootAttribute( Namespace = "", IsNullable = false )]
public class SyncTimes
{
    private LastSyncTime[] items;

    [System.Xml.Serialization.XmlElementAttribute( "LastSyncTime", Form = System.Xml.Schema.XmlSchemaForm.Unqualified )]
    public LastSyncTime[] Items
    {
        get
        {
            return items;
        }
        set
        {
            items = value;
        }
    }


    public static SyncTimes OpenXml( string path )
    {
        SyncTimes syncTimes;
        using ( FileStream stream = File.OpenRead( path ) )
        {
            XmlSerializer x = new XmlSerializer( typeof( SyncTimes ) );
            syncTimes = (SyncTimes)x.Deserialize( stream );
        }

        return syncTimes;
    }

    public void ToXmlFile( string path )
    {
        using ( FileStream stream = File.Create( path ) )
        {
            XmlSerializer x = new XmlSerializer( typeof( SyncTimes ) );
            x.Serialize( stream, this );
        }
    }
}

然后您的代码可以像这样使用 xml 文件:

SyncTimes times = SyncTimes.OpenXml("data.xml");
var archived = times.Where(x => x.Time < DateTime.Now.AddMonths(-months));