我们将数据库定义以XML格式存储在本问题末尾的格式中。我遇到的问题是获取模式列表,这些模式中的表,这些表中的列(所有这些都带有相关信息)。我当前的代码(包含在示例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元素(例如表注释或大小字段,它们不适用于所有数据类型)。
谢谢!
答案 0 :(得分:1)
以下是保存嵌套结构的方法。将XElement添加到匿名类型以用作嵌套查询的源。
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包含空元素,如此列的注释:
<column>
<name>column_name4</name>
<type>data_type4</type>
<size>4</size>
<nullable>not null4</nullable>
<comment/>
</column>
这将在查询中返回一个空字符串,因此请将代码更改为:
if (!string.IsNullOrEmpty(c.comment))
{
column_create += " COMMENT '" + c.comment + "'";
}