在 C# 中循环遍历 XML 的特定节点

Posted

技术标签:

【中文标题】在 C# 中循环遍历 XML 的特定节点【英文标题】:Loop through specific Node of XML in C# 【发布时间】:2021-07-16 03:15:03 【问题描述】:

我进行了很多研究,但我无法找到解决我的特定问题的方法。我必须读取 C# 中的外部 xml 文件并读取对象中的值。这是我的 xml 文件的快照:

 <DatabaseList>
  <DatabaseDetails>
    <ConnectionId>1</ConnectionId>
    <ConnectionName>MyConn1</ConnectionName>
    <ServerConnection xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
      <CobConnection>
        <CobConnection />
        <ConnectionType>MSSQL</ConnectionType>
        <Database />
        <Server />
      </CobConnection>
      <ConnectionType>MSSQL</ConnectionType>
      <Database>MyDB1</Database>
      <Port>2431</Port>
      <Server>MyServerName1</Server>
    </ServerConnection>
  </DatabaseDetails>
  <DatabaseDetails>
    <ConnectionId>2</ConnectionId>
    <ConnectionName>MyConn2</ConnectionName>
    <ServerConnection xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
      <CobConnection>
        <CobConnection />
        <ConnectionType>MSSQL</ConnectionType>
        <Database />
        <Server />
      </CobConnection>
      <ConnectionType>MSSQL</ConnectionType>
      <Database>MyDB2</Database>
      <Port>2431</Port>
      <Server> MyServerName2</Server>
    </ServerConnection>
  </DatabaseDetails>
</DatabaseList>

例如,ConnectionName = MyConn2 被传递给下面的过程,代码应该读取 MyConn2 的值。但就我而言,我正确选择了 xmlNodesLvl2,但它从文件的开头开始。我需要读取上一步中刚刚找到的节点的值。对于那个特定的 Database.ConnectionName,我需要读取节点值,例如 Database、ConnectionType、Server 等。但我将从头开始下一步。我在代码中添加了注释 //Problem here.

public static void GetInfo(string ConnectionName)
          
    XmlDocument xmlDoc = new XmlDocument();
    bool bfound = false;
    xmlDoc.Load(@"C:\path..\Database.xml");
    XmlNodeList xmlNodesLvl1 = xmlDoc.SelectNodes("DatabaseList/DatabaseDetails");
    foreach (XmlNode xmlNode in xmlNodesLvl1)
    
        if (xmlNode.HasChildNodes)
        
            foreach (XmlNode item in xmlNode.ChildNodes)
            
                string tagName = item.Name;
                if (tagName == "ConnectionId")
                
                    Database.ConnectionId = item.InnerText;
                
                if (tagName == "ConnectionName")
                
                    if (item.InnerText == ConnectionName)
                    
                        Database.ConnectionName = item.InnerText;
                        bfound = true;
                        XmlNodeList xmlNodesLvl2 = null;
                        //Problem here

                        if (Enviroment == "COB")
                        
                            xmlNodesLvl2 = xmlDoc.SelectNodes("DatabaseList/DatabaseDetails/ServerConnection/CobConnection");
                        
                        else
                        
                            xmlNodesLvl2 = xmlDoc.SelectNodes("DatabaseList/DatabaseDetails/ServerConnection");
                                                        
                        foreach (XmlNode xmlNodeLvl2 in xmlNodesLvl2)
                        
                            if (xmlNodeLvl2.HasChildNodes)
                            
                                foreach (XmlNode itemLvl2 in xmlNodeLvl2.ChildNodes)
                                
                                    if (itemLvl2.Name == "CobConnection")
                                    
                                        Database.CobConnection = itemLvl2.InnerText;
                                    
                                    if (itemLvl2.Name == "Database")
                                    
                                        Database.Name = itemLvl2.InnerText;
                                    
                                    if (itemLvl2.Name == "ConnectionType")
                                    
                                        Database.ConnectionType = itemLvl2.InnerText;
                                    
                                    if (itemLvl2.Name == "Server")
                                    
                                        Database.Server = itemLvl2.InnerText;
                                    
                                
                                if (bfound == true)
                                
                                    break;
                                
                            
                        
                        if (bfound == true)
                        
                            break;
                        
                    
                
            
            if (bfound == true)
            
                break;
            
        
    

请指教!

【问题讨论】:

【参考方案1】:

尝试放入DataTable

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication1

    class Program
    
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        
            XDocument doc = XDocument.Load(FILENAME);

            DataTable dt = new DataTable();
            dt.Columns.Add("ConnectionId",typeof(string));
            dt.Columns.Add("ConnectionName",typeof(string));
            dt.Columns.Add("CobConnection",typeof(string));
            dt.Columns.Add("CobConnectionType",typeof(string));
            dt.Columns.Add("CobDatabase",typeof(string));
            dt.Columns.Add("CobServer",typeof(string));
            dt.Columns.Add("ConnectionType",typeof(string));
            dt.Columns.Add("Database",typeof(string));
            dt.Columns.Add("Port",typeof(string));
            dt.Columns.Add("Server", typeof(string));

            List<XElement> details = doc.Descendants("DatabaseDetails").ToList();

            foreach (XElement detail in details)
            
                string id = (string)detail.Element("ConnectionId");
                string name = (string)detail.Element("ConnectionName");

                XElement xCobConnection = detail.Descendants("CobConnection").FirstOrDefault();

                string cobConnection = (string)xCobConnection.Element("CobConnection");
                string cobType = (string)xCobConnection.Element("ConnectionType");
                string cobDatabase = (string)xCobConnection.Element("Database");
                string cobServer = (string)xCobConnection.Element("Server");
    
                XElement serverConnection = detail.Element("ServerConnection");
                string connectionType = (string)serverConnection.Element("ConnectionType");
                string database = (string)serverConnection.Element("Database");
                string port = (string)serverConnection.Element("Port");
                string server = (string)serverConnection.Element("Server");

                dt.Rows.Add(new object[] 
                    id,
                    name,
                    cobConnection,
                    cobType,
                    cobDatabase,
                    cobServer,
                    connectionType,
                    database,
                    port,
                    server
                );
            

        
    

【讨论】:

以上是关于在 C# 中循环遍历 XML 的特定节点的主要内容,如果未能解决你的问题,请参考以下文章

计算特定XML节点c#的子节点数[重复]

VBA 循环遍历 XML 节点并在每个节点中获取值

在 SSIS 中,如何在 Foreach NodeList 枚举器中使用 XPATH 循环遍历特定元素内的 XML

C#不能查询XML但可以遍历节点?

循环遍历 XML 并找到文本节点 - Jquery

循环遍历XML节点并重用元素