2009-05-15 6 views
2

우리는 데이터베이스 정의를이 질문 끝에 형식으로 XML로 저장합니다. 내가 겪고있는 문제는 스키마 목록, 스키마의 테이블, 해당 테이블의 열 (모든 관련 정보 포함)을 얻는 것입니다. 내 현재 코드 (예제 XML 아래 포함)는 모든 것을 포착하고 중첩을 완전히 무시하고 여러 스키마로 인해 각 테이블/열을 여러 번 반환합니다.DDL을 생성하기위한 Linq와 XML

샘플 XML :

<schemas> 
    <schema> 
     <name>schema_name1</name> 
     <tables> 
      <table> 
       <name>table_name2</name> 
       <comment>comment string2</comment> 
       <type>innodb2</type> 
       <columns> 
        <column> 
         <name>column_name3</name> 
         <type>data_type3</type> 
         <size>3</size> 
         <nullable>not null3</nullable> 
         <comment>comment string3</comment> 
        </column> 
        <column> 
         <name>column_name4</name> 
         <type>data_type4</type> 
         <size>4</size> 
         <nullable>not null4</nullable> 
         <comment>comment string4</comment> 
        </column> 
       </columns> 
      </table> 
     </tables> 
    </schema> 
    <schema> 
     <name>schema_name5</name> 
     <tables> 
      <table> 
       <name>table_name6</name> 
       <comment>comment string6</comment> 
       <type>innodb6</type> 
       <columns> 
        <column> 
         <name>column_name7</name> 
         <type>data_type7</type> 
         <size>7</size> 
         <nullable>not null7</nullable> 
         <comment>comment string7</comment> 
        </column> 
       </columns> 
      </table> 
     </tables> 
    </schema> 
</schemas> 

C# 코드 : 중첩 구조를 유지하는 방법에 대한

XDocument xml_input = XDocument.Load(FILE_IN); 
    string column_create = ""; 
    //build a list of all schemas in xml 
    var schemas = from s in xml_input.Descendants("schema") 
        select new 
        { 
         name = s.Element("name").Value 
        }; 
    //loop through all schemas 
    foreach (var s in schemas) 
    { 
     //write the schema creation lines 
     Console.WriteLine("DROP SCHEMA IF EXISTS " + s.name + ";"); 
     Console.WriteLine("CREATE SCHEMA " + s.name + ";"); 
     //build a list of all tables in schema 
     var tables = from t in xml_input.Descendants("schema") 
             .Descendants("table") 
        select new 
        { 
         name = t.Element("name").Value, 
         comment = t.Element("comment").Value, 
         type = t.Element("type").Value 
        }; 
     //loop through all tables in schema 
     foreach (var t in tables) 
     { 
      //write the beginning of the table creation lines 
      Console.WriteLine("CREATE TABLE " + s.name + "." + t.name + " ("); 
      //build a list of all columns in the schema 
      var columns = from c in xml_input.Descendants("schema") 
              .Descendants("table") 
              .Descendants("column") 
          select new 
          { 
           name = c.Element("name").Value, 
           type = c.Element("type").Value, 
           size = c.Element("size").Value, 
           comment = c.Element("comment").Value 
          }; 
      //loop through all columns in table 
      foreach (var c in columns) 
      { 
       //build the column creation line 
       column_create = c.name + " " + c.type; 
       if (c.size != null) 
       { 
        column_create += "(" + c.size + ")"; 
       } 
       if (c.comment != null) 
       { 
        column_create += " COMMENT '" + c.comment + "'"; 
       } 
       column_create += ", "; 
       //write the column creation line 
       Console.WriteLine(column_create); 
      } 
      //write the end of the table creation lines 
      Console.WriteLine(")"); 
      if (t.comment != null) 
      { 
       Console.WriteLine("COMMENT '" + t.comment + "'"); 
      } 
      if (t.type != null) 
      { 
       Console.WriteLine("TYPE = " + t.type); 
      } 
      Console.WriteLine(";"); 
     } 
    } 

어떤 아이디어? 선택적 XML 요소 (예 : 모든 데이터 유형에 적용되지 않는 테이블 주석 또는 크기 필드)를 처리하는 데 문제가 있습니다.

감사합니다.

답변

1

중첩 된 구조를 유지하는 방법은 다음과 같습니다. XElement를 익명 형식에 추가하여 중첩 쿼리의 원본으로 사용합니다.

 <column> 
     <name>column_name4</name> 
     <type>data_type4</type> 
     <size>4</size> 
     <nullable>not null4</nullable> 
     <comment/> 
     </column> 

이 조회에서 빈 문자열을 반환합니다 : 옵션 요소를 다루는

XDocument xml_input = XDocument.Load(FILE_IN); 
     string column_create = ""; 
     //build a list of all schemas in xml 
     var schemas = from s in xml_input.Descendants("schema") 
         select new 
         { 
          schema = s, 
          name = s.Element("name").Value 
         }; 
     //loop through all schemas 
     foreach (var s in schemas) 
     { 
      //write the schema creation lines 
      Console.WriteLine("DROP SCHEMA IF EXISTS " + s.name + ";"); 
      Console.WriteLine("CREATE SCHEMA " + s.name + ";"); 
      //build a list of all tables in schema 
      var tables = from t in s.schema.Descendants("table") 
         select new 
         { 
          table = t, 
          name = t.Element("name").Value, 
          comment = t.Element("comment").Value, 
          type = t.Element("type").Value 
         }; 
      //loop through all tables in schema 
      foreach (var t in tables) 
      { 
       //write the beginning of the table creation lines 
       Console.WriteLine("CREATE TABLE " + s.name + "." + t.name + " ("); 
       //build a list of all columns in the schema 
       var columns = from c in t.table.Descendants("column") 
           select new 
           { 
            name = c.Element("name").Value, 
            type = c.Element("type").Value, 
            size = c.Element("size").Value, 
            comment = c.Element("comment").Value 
           }; 
       //loop through all columns in table 
       foreach (var c in columns) 
       { 
        //build the column creation line 
        column_create = c.name + " " + c.type; 
        if (c.size != null) 
        { 
         column_create += "(" + c.size + ")"; 
        } 
        if (c.comment != null) 
        { 
         column_create += " COMMENT '" + c.comment + "'"; 
        } 
        column_create += ", "; 
        //write the column creation line 
        Console.WriteLine(column_create); 
       } 
       //write the end of the table creation lines 
       Console.WriteLine(")"); 
       if (t.comment != null) 
       { 
        Console.WriteLine("COMMENT '" + t.comment + "'"); 
       } 
       if (t.type != null) 
       { 
        Console.WriteLine("TYPE = " + t.type); 
       } 
       Console.WriteLine(";"); 
      } 
     } 

한 가지 방법은이 칼럼의 코멘트와 같이 값이없는 때 XML은 빈 요소를 포함하는 것입니다 코드를 다음과 같이 변경하십시오.

if (!string.IsNullOrEmpty(c.comment)) 
    { 
     column_create += " COMMENT '" + c.comment + "'"; 
    } 
+0

환상적입니다. 매력처럼 작동합니다! – Mike