C# 使用Xdocument检索xml的子元素

C# 使用Xdocument检索xml的子元素,c#,xml,xml-parsing,linq-to-xml,C#,Xml,Xml Parsing,Linq To Xml,我想像这样解析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=""&

我想像这样解析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 (XNode field in xdoc.Descendants("table").Nodes())
这是在所有
元素下查找所有节点。你不会想要的

您已经将要查看的表作为一个
XElement
——因此请使用它。它要求您的
变量是一个
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
    }
}

请注意,当您已经有一个元素时,获取属性是多么简单。在绝大多数情况下,您确实不需要执行多个解析操作。还要注意我是如何将
bool
转换为
primarykey
identity
的。同样,这比手动测试字符串更干净。

这里是解析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");
        // ...
    }

}

我建议您阅读文章。

使用XElement而不是XNode

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");
        // ...
    }

}