LINQ - 根据值删除元素

时间:2015-03-31 19:19:16

标签: c# xml linq linq-to-xml

以下是我的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();
    }

目前我正在使用零来运行该方法以查看它是否运行。

这就是我得到的:

enter image description here

对我而言,这似乎导致了空例外:

element.Attribute("SyncTime").Value

但基于查看XML为何会发生这种情况,我不明白。

2 个答案:

答案 0 :(得分:2)

<SyncTime>不是属性 - 它是一个元素。因此,表达式element.Attribute("SyncTime")返回null,并且尝试访问Value会抛出空引用异常。

答案 1 :(得分:0)

使用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));