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));
这是我的 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));