2015-01-20 3 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, чтобы узнать, что вызывает вопрос, на который можно получить ответ. –

+1

Вы пробовали _anything_? Как вы обрабатываете XML в своей программе на C#? Пожалуйста, покажите, что вы сделали до сих пор, так что ответ может основываться на этом должным образом. –

+0

Какой элемент вы пытаетесь удалить? Весь элемент SyncTable или только элемент Cal_StartDateTime внутри? Или, возможно, элемент SyncEntry? – Holf

ответ

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 должен иметь один корневой элемент. В вашем вопросе & комментарии подразумевают, что у вас несколько SyncTables, поэтому я добавил корневой элемент, чтобы сделать это действительным (SyncTables).

Код ниже будет просматривать каждое значение Cal_StartDateTime в SyncTable, а затем использовать максимальное значение, найденное как сравнение с 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 для выбора всех записей, которые равны или новее, чем сегодня, вместо того, чтобы выбирать старые и удалять их в цикле? –

+0

Я скорректировал удаление SyncTable, а не SyncEntry, в соответствии с комментарием, добавленным в ваш вопрос. Также добавлен '.Date' в 'DateTime.Now', то есть он будет использовать только часть даты, т. Е. 00:00 этим утром. – Holf

+0

Если вы хотите использовать Linq для выбора записей, то вам нужно будет создать отдельный XML-документ, в который их можно разместить. Лично я считаю, что легче выбрать, что нужно удалить, и удалить его из исходного документа. Linq XML-классы (такие как XElement) немного необычны в таких операциях, как «Удалить()» для исходного объекта. Но вы можете попробовать другие способы, если хотите. :-) – Holf

Смежные вопросы