Linq to XML 生成 DDL
我们以本问题末尾的格式将数据库定义存储为 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 元素(例如表注释或大小字段,这不适用于所有数据类型)时也遇到了麻烦。
谢谢!
We're storing out database definition as XML in the format at the end of this question. The problem I'm having is getting a list of schemas, the tables in those schemas, the columns in those tables (all with their associated information). My current code (included below the sample XML) grabs everything, completely ignoring nesting and, due to the multiple schemas, returns each table/column multiple times.
Sample 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# Code:
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(";");
}
}
Any ideas on how to preserve the nesting structure? I'm also having trouble handling optional XML elements (such as the table comment or the size field, which wouldn't apply to all data types).
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
以下是如何保留嵌套结构。 将 XElement 添加到匿名类型以用作嵌套查询的源。
处理可选元素的一种方法是,当没有值时,您的 xml 包含空元素,如本列注释中所示:
这将在您的查询中返回一个空字符串,因此请将代码更改为:
Here is how to preserve your nested structure. Add the XElement to your anonymous type to use as the source of your nested queries.
One way to deal with the optional elements is for your xml to contain empty elements when there is no value as in this column's comment:
This will return an empty string in your query, so change the code to this: