2013-08-06 2 views
1
<ndActivityLog repositoryId="AA-AAAA1AAA" repositoryName="Company Name" startDate="2013-07-05" endDate="2013-07-06"> 
    <activity date="2013-07-05T06:42:35" name="open" host="00.00.00.00"> 
     <user id="[email protected]" name="Joe Bloggs" memberType="I" /> 
     <storageObject docId="0000-0000-0000" name="Opinion" size="356864" fileExtension="doc"> 
      <cabinet name="Client and Matters">NG-5MIYABBV</cabinet> 
      <DocumentType>Legal Document</DocumentType> 
      <Author>Joe Bloggs</Author> 
      <Matter>1001</Matter> 
      <Client>R1234</Client> 
     </storageObject> 
    </activity> 
</ndActivityLog> 

Это пример XML. В документе содержится около 4000 элементов «деятельности» с различными уровнями контента. У некоторых есть элементы «Клиент» и «Материя», другие - нет. Чтобы думать об этом как о таблице, это были бы пустые ячейки, но заголовки столбцов все еще существуют.Сложный вложенный XML-анализ в C#

Мне по существу нужно проанализировать это в базе данных SQL, сохраняя структуру данных. Кроме того, если элемент не существует в некоторых примерах, он должен ссылаться на этот факт и оставить его «пустой ячейкой».

var doc = XDocument.Load(path + "\\" + file + ".xml"); 

     var root = doc.Root; 
     foreach (XElement el in root.Elements()) 
     { 

       // Console.WriteLine(el.Nodes()); 
       // Console.WriteLine(el.Value); 
       //Console.WriteLine(" Attributes:"); 
       foreach (XAttribute attr in el.Attributes()) 
       { 

        Console.WriteLine(attr); 
       // Console.WriteLine(el.Elements("id")); 


       } 

      Console.WriteLine("---------------------------"); 

      // foreach (XElement element in el.Elements()) 
     // { 

    //   Console.WriteLine(" {0}: {1}", element.Name, element.Value); 
     //  } 

      } 
      //hold console open 
      Console.ReadLine(); 

     } 

Код до сих пор. Выходной сигнал показан ниже

date="2013-07-06T17:07:42" 
name="open" 
host="213.146.142.50 

Мне в основном нужна вся информация, которую нужно извлечь, поэтому я могу хранить их по существу в виде таблицы. Я разумно новичок в синтаксическом анализе XML, поэтому любая помощь будет оценена по достоинству.

+1

Есть ли особая причина, по которой вы хотите разобрать ее вручную? Почему бы не создать соответствующие классы C# и десериализовать его в эти классы? – derape

+1

Почему бы вам не сериализовать его http://msdn.microsoft.com/en-us/library/58a18dwa.aspx – Krishna

+0

@derape i был в предположении, что мне пришлось это делать с помощью 'XDocument' или LINQ –

ответ

0

Только вы знаете разрешенный кабинет имен атрибутов ... Клиент. Простой способ грубой силы - извлечь каждый из ожидаемых атрибутов, а затем вы узнаете, какие из них отсутствуют, и может установить, что ячейка пуста. Foreach будет только перебирать то, что присутствует на каждом элементе - он не может угадать недостающие.

0

Я думаю, вы могли бы решить проблему следующим образом:

  1. Вы создаете класс с именем BaseNode.

  2. создаются классы, которые расширяют BaseNode для всех ваших типов сущностей

  3. Вы можете создать набор правил, на основе узла определить предпочтительный тип объекта

  4. Вы создаете метод generateEntity в вашем Класс BaseNode.

  5. Вы можете использовать этот алгоритм (это не код, так что не пытайтесь скомпилировать)

ParseXML (узел)

for each node in node do 

    BaseNode.generateEntity(node.input) 

    if (node.hasChildren()) 

     parseXML(node) 

    end if 

end for 

конец ParseXML

Конечно, вы должны хранить и анализировать созданные объекты.

0

Я не говорят, что это лучший или правильный способ решить конкретную проблему, однако, я обеспечиваю как сокращенном пример того, что вы могли бы сделать (отсюда отсутствие исключений/обработки ошибок и т.д.).

namespace so.consoleapp 
{ 
    using System; 
    using System.Collections.Generic; 
    using System.Xml.Linq; 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      var doc = XElement.Load("file.xml"); 
      var activityElements = doc.Elements("activity"); 

      ICollection<Activity> collectionOfActivities = new List<Activity>(); 
      foreach (var activityElement in activityElements) 
      { 
       var storageObjectElement = activityElement.Element("storageObject"); 

       string clientElement = null; 
       if (storageObjectElement.Element("Client") != null) 
       { 
        clientElement = storageObjectElement.Element("Client").Value; 
       } 

       var newStorageObject = new StorageObject 
       { 
        Client = clientElement, 
        Author = storageObjectElement.Element("Author").Value 
       }; 

       var userElement = activityElement.Element("user"); 
       var newUser = new User 
       { 
        Id = userElement.Attribute("id").Value, 
        Name = userElement.Attribute("name").Value, 
        MemberType = userElement.Attribute("memberType").Value 
       }; 

       collectionOfActivities.Add 
       (
        new Activity 
        { 
         Date = activityElement.Attribute("date").Value, 
         Name = activityElement.Attribute("name").Value, 
         Host = activityElement.Attribute("host").Value, 
         User = newUser, 
         StorageObject = newStorageObject 
        } 
       ); 
      } 

      Console.ReadLine(); 
     } 
    } 

    class Activity 
    { 
     public string Date 
     { 
      get; 
      set; 
     } 

     public string Name 
     { 
      get; 
      set; 
     } 

     public string Host 
     { 
      get; 
      set; 
     } 

     public User User 
     { 
      get; 
      set; 
     } 

     public StorageObject StorageObject 
     { 
      get; 
      set; 
     } 
    } 

    class User 
    { 
     public string Id 
     { 
      get; 
      set; 
     } 

     public string Name 
     { 
      get; 
      set; 
     } 

     public string MemberType 
     { 
      get; 
      set; 
     } 
    } 

    class StorageObject 
    { 
     public string Client 
     { 
      get; 
      set; 
     } 

     public string Author 
     { 
      get; 
      set; 
     } 
    } 
} 
0

Попробуйте что-нибудь подобное. Создать новую Windows Forms Application, добавьте один DataGrid элемент управления в форму и код позади, как показано ниже:

private void Form1_Load(object sender, EventArgs e) 
     { 
      populate_datagrid(dataGridView1); 
     } 

     private void populate_datagrid(DataGridView dataGridView1) 
     { 
      String xml_string = @"<ndActivityLog repositoryId=""AA-AAAA1AAA"" repositoryName=""Company Name"" startDate=""2013-07-05"" endDate=""2013-07-06""> 
            <activity date=""2013-07-05T06:42:35"" name=""open"" host=""00.00.00.00""> 
             <user id=""[email protected]"" name=""Joe Bloggs"" memberType=""I"" /> 
             <storageObject docId=""0000-0000-0000"" name=""Opinion"" size=""356864"" fileExtension=""doc""> 
              <cabinet name=""Client and Matters"">NG-5MIYABBV</cabinet> 
              <DocumentType>Legal Document</DocumentType> 
              <Author>Joe Bloggs</Author> 
              <Matter>1001</Matter> 
              <Client>R1234</Client> 
             </storageObject> 
            </activity> 
            <activity date=""2013-06-05T06:42:35"" name=""close"" host=""00.00.00.00""> 
             <user id=""[email protected]"" name=""abc"" memberType=""I"" /> 
             <storageObject docId=""0000-0000-0000"" name=""Opinion"" size=""25630"" fileExtension=""doc""> 
              <cabinet name=""Client and Matters"">NG-5MIYABBV</cabinet> 
              <DocumentType>Legal Document</DocumentType> 
              <Author>abc</Author> 
              <Client>R1234</Client> 
             </storageObject> 
            </activity> 
            <activity date=""2013-06-05T06:42:35"" name=""unknown"" host=""00.00.00.00""> 
             <user id=""[email protected]"" name=""bca"" memberType=""I"" /> 
             <storageObject docId=""0000-0000-0000"" name=""Opinion"" size=""45875"" fileExtension=""doc""> 
              <cabinet name=""Client and Matters"">NG-5MIYABBV</cabinet> 
              <DocumentType>Legal Document</DocumentType> 
              <Author>bca</Author> 
              <Matter>1001</Matter> 
             </storageObject> 
            </activity> 
            <activity date=""2013-06-05T06:42:35"" name=""open"" host=""00.00.00.00""> 
             <user id=""[email protected]"" name=""cab"" memberType=""I"" /> 
             <storageObject docId=""0000-0000-0000"" name=""Opinion"" size=""45875"" fileExtension=""doc""> 
              <cabinet name=""Client and Matters"">NG-5MIYABBV</cabinet> 
              <DocumentType>Legal Document</DocumentType> 
             </storageObject> 
            </activity> 
           </ndActivityLog>"; 

      var query = from XElement c in System.Xml.Linq.XElement.Parse(xml_string).Descendants("activity") 
         select new 
         { 
          user = c.Elements("user").First().Attribute("name").Value, 
          author = c.Descendants("Author").Count() > 0 ? c.Descendants("Author").First().Value : "n/a", 
          matter = c.Descendants("Matter").Count() > 0 ? c.Elements("Matter").First().Value : "n/a" 
         }; 

      dataGridView1.DataSource = query.ToList(); 

     } 

Надеюсь, что это помогает.

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