使用Xdocument检索xml的子元素
本文关键字:元素 xml Xdocument 检索 使用 | 更新日期: 2024-09-12 16:43:20
我想解析这样的XML文件:
<?xml version="1.0" encoding="utf-8" ?>
<database name="myDb">
<table name="myTable">
<field name="Code" type="int" size="0" identity="true" primarykey="true" description="کد شناسه" reference=""></field>
<field name="Name" type="nvarchar" size="50" identity="false" primarykey="false" description="نام شخص" reference=""></field>
</table>
<table name="yourTable">
<field name="Code" type="int" size="0" identity="true" primarykey="true" description="کد شناسه" reference=""></field>
<field name="Title" type="nvarchar" size="50" identity="false" primarykey="false" description="نام شخص" reference=""></field>
</table>
</database>
问题是,在我的内部foreach中,它将解析4个字段,而不是与每个表相关的2个字段。如何将代码更改为只读取当前表的字段?
XDocument xdoc = XDocument.Load("d:''tables.xml");
foreach (XNode table in xdoc.Descendants("database").Nodes())
{
fields = "";
tableName = XElement.Parse(table.ToString()).Attribute("name").Value;
//XElement xE = XElement.Parse(table.ToString());
//foreach (XElement e in xE.Elements())
foreach (XNode field in xdoc.Descendants("table").Nodes())
{
fieldName = XElement.Parse(field.ToString()).Attribute("name").Value;
type = XElement.Parse(field.ToString()).Attribute("type").Value;
size = XElement.Parse(field.ToString()).Attribute("size").Value;
identity = XElement.Parse(field.ToString()).Attribute("identity").Value;
primarykey = XElement.Parse(field.ToString()).Attribute("primarykey").Value;
description = XElement.Parse(field.ToString()).Attribute("description").Value;
reference = XElement.Parse(field.ToString()).Attribute("reference").Value;
if (identity == "true") identity = "identity";
if (primarykey == "true") primarykey = "primary key";
if (isChar(type))
{
fields += string.Format(fieldCharTemplate, fieldName, type, size);
}
else
{
fields += string.Format(fieldNonCharTemplate, fieldName, type, identity,primarykey);
}
//var y = x.Element("type");
}
sql = string.Format(tableTemplate, tableName, fields);
Response.Write(sql);
}
这就是问题所在:
foreach (XNode field in xdoc.Descendants("table").Nodes())
这是在alltable
元素下查找all节点。你不想那样。
您已经得到了您正在查看的表作为XElement
,所以请使用它。它要求您的table
变量是XElement
,而不仅仅是XNode
,但这正是您真正想要的。。。这意味着你不需要重新分析它就可以得到表名。我会把你的代码写成:
foreach (XElement table in xdoc.Root.Elements("table"))
{
string tableName = (string) table.Attribute("name");
StringBuilder fields = new StringBuilder();
foreach (XElement field in table.Elements("field"))
{
string fieldName = (string) field.Attribute("name");
string type = (string) field.Attribute("type");
// Consider casting to int instead...
string size = (string) field.Attribute("size");
bool identity = (bool) field.Attribute("identity");
bool primaryKey = (bool) field.Attribute("primarykey");
string description = (string) field.Attribute("description");
string reference = (string) field.Attribute("reference");
// Append to fields here
}
}
请注意,当您已经有了一个元素时,获取属性要简单得多。在绝大多数情况下,您确实不需要执行多个解析操作。还要注意我是如何将primarykey
和identity
转换为bool
的。同样,这比手动测试字符串更干净。
以下是解析xml的正确方法。表和字段是元素,所以将它们作为元素:
// instead xdoc.Descendants("database").Nodes()
xdoc.Descendants("table") // returns all table elements
获取元素或属性值时也要使用强制转换。如果找不到节点,它不会抛出异常,如果需要解析为bool、integer等,它会简化代码:
XDocument xdoc = XDocument.Load("d:''tables.xml");
foreach (XElement table in xdoc.Root.Elements("table"))
{
tableName = (string)table.Attribute("name");
foreach (XElement field in table.Elements("field"))
{
fieldName = (string)field.Attribute("name");
type = (string)field.Attribute("type");
size = (int)field.Attribute("size"); // that will be an integer
identity = (bool)field.Attribute("identity"); // boolean
primarykey = (bool)field.Attribute("primarykey"); // boolean
description = (string)field.Attribute("description");
reference = (string)field.Attribute("reference");
// ...
}
}
我建议您阅读查询XML树的文章。
使用XElement而不是XNode。