2015-01-20 183 views
-4

舊的在C#應用程序中刪除節點,如果我有以下XML:與日期值比今天

<SyncTable> 
    <SyncEntry> 
    <Cal_ID>1234</Cal_ID> 
    <Cal_LastUpdated>2015-01-20T14:25:34.828-05:00</Cal_LastUpdated> 
    <Cal_StartDateTime>2015-01-22T20:05:00-05:00</Cal_StartDateTime> 
    </SyncEntry> 
    <SyncEntry> 
    <Cal_ID>4567</Cal_ID> 
    <Cal_LastUpdated>2015-01-20T11:00:24.988-05:00</Cal_LastUpdated> 
    <Cal_StartDateTime>2015-02-10T18:30:00-05:00</Cal_StartDateTime> 
    </SyncEntry> 
</SyncTable> 

如何搜索和刪除條目<SyncTable>其中<Cal_StartDateTime>的條目比今天更舊?

+2

您能舉出一個您嘗試過的代碼示例,或者您在解決方案時遇到的特定問題嗎?閱讀https://stackoverflow.com/help/mcve以查看可能得到解答的問題。 – 2015-01-20 20:23:20

+1

你試過_anything_嗎?你在C#程序中如何處理XML?請說明迄今爲止已完成的工作,以便能夠正確地建立答案。 – 2015-01-20 20:23:25

+0

你試圖刪除哪個元素?整個SyncTable元素還是隻是Cal_StartDateTime元素中的?或者可能是SyncEntry元素? – Holf 2015-01-20 20:26:30

回答

0

這裏是做你想要的東西的一種方式:

string xml = @" 
    <SyncTable> 
    <SyncEntry> 
     <Cal_ID>1234</Cal_ID> 
     <Cal_LastUpdated>2015-01-20T14:25:34.828-05:00</Cal_LastUpdated> 
     <Cal_StartDateTime>2015-01-22T20:05:00-05:00</Cal_StartDateTime> 
    </SyncEntry> 
    <SyncEntry> 
     <Cal_ID>4567</Cal_ID> 
     <Cal_LastUpdated>2015-01-20T11:00:24.988-05:00</Cal_LastUpdated> 
     <Cal_StartDateTime>2015-02-10T18:30:00-05:00</Cal_StartDateTime> 
    </SyncEntry> 
    </SyncTable> 
    "; 

    XmlDocument doc = new XmlDocument() ; 
    doc.LoadXml(xml) ; 

    DateTime  dtNow = DateTime.UtcNow ; 
    DateTimeStyles style = DateTimeStyles.AssumeUniversal 
         | DateTimeStyles.AdjustToUniversal 
         | DateTimeStyles.AllowWhiteSpaces 
         ; 
    foreach(XmlNode node in doc.SelectNodes("/SyncTable/SyncEntry/Cal_StartDateTime")) 
    { 
    DateTime startDate ; 
    bool isValid = DateTime.TryParseExact(node.InnerText , "yyyy-MM-ddTHH:mm:ssK" , CultureInfo.InvariantCulture , style , out startDate) ; 
    if (!isValid || startDate < dtNow) 
    { 
     doc.DocumentElement.RemoveChild(node.ParentNode); 
    } 
    } 

在這一點上,doc已全部違規去除<SyncEnctry>元素。

0

有效的XML文檔必須具有單個根元素。您的問題&註釋意味着您有多個SyncTable,因此我添加了一個根元素以使其生效(SyncTables)。

下面的代碼將查看SyncTable中的每個Cal_StartDateTime值,然後使用找到的最大值作爲與DateTime.Now.Date的比較結果。

如果您希望使用最小值,請將Max替換爲Min

class Program 
{ 
    static void Main(string[] args) 
    { 
     var xmlString = @"<SyncTables> 
<SyncTable> 
    <SyncEntry> 
    <Cal_ID>1234</Cal_ID> 
    <Cal_LastUpdated>2015-01-20T14:25:34.828-05:00</Cal_LastUpdated> 
    <Cal_StartDateTime>2015-01-22T20:05:00-05:00</Cal_StartDateTime> 
    </SyncEntry> 
    <SyncEntry> 
    <Cal_ID>4567</Cal_ID> 
    <Cal_LastUpdated>2015-01-10T11:00:24.988-05:00</Cal_LastUpdated> 
    <Cal_StartDateTime>2015-02-10T18:30:00-05:00</Cal_StartDateTime> 
    </SyncEntry> 
</SyncTable> 
</SyncTables>"; 

     var xml = XElement.Parse(xmlString); 

     var syncTablesToRemove = 
      xml.Elements("SyncTable") 
       .Where(x => 
        x.Descendants("Cal_StartDateTime") 
         .Select(y => DateTime.Parse(y.Value)).Max() < DateTime.Now.Date); 

     foreach (var syncEntry in syncTablesToRemove) 
     { 
      syncEntry.Remove(); 
     } 

     Console.WriteLine(xml); 

     Console.ReadLine(); 
    } 
} 
+0

「比今天早」,不包含DateTime.Now包含時間嗎?另外,使用linq選擇等於或者比今天更新的所有記錄不是更容易,而不是選擇舊的並在循環中刪除它們? – 2015-01-20 20:53:01

+0

我調整了刪除SyncTable,而不是SyncEntry,根據您添加到您的問題的評論。 還將'.Date'添加到'DateTime.Now',這意味着它只會使用日期部分,即今天早上的00:00。 – Holf 2015-01-20 20:56:44

+0

如果您想使用Linq來選擇要保留的記錄,那麼您需要構建一個單獨的XML文檔來放置它們。就我個人而言,我認爲選擇需要刪除的內容並將其從原始文檔中刪除會更容易。 Linq XML類(如XElement)有點不尋常,因爲像'Remove()'這樣的操作對原始對象起作用。但如果您願意,歡迎您嘗試其他方式。 :-) – Holf 2015-01-20 21:03:52