如何在 Select 节点中遍历 XML 中的所有元素
How to iterate through all element in XML in Select Nodes
我真的是 c# 新手。我正在创建一个项目,我需要从 XML 文件中提取数据。我可以 select 一个节点并循环遍历该元素的内部文本。但是我在 XML 文件中有几个元素。我想在一列中一次循环遍历所有元素。我怎么能这样做。我在详细解释。
这是我的 XML 文件。
<?xml version="1.0" encoding="utf-8"?>
<tlp:WorkUnits xmlns:tlp="http://www.timelog.com/XML/Schema/tlp/v4_4"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.timelog.com/XML/Schema/tlp/v4_4 http://www.timelog.com/api/xsd/WorkUnitsRaw.xsd">
<tlp:WorkUnit ID="130">
<tlp:EmployeeID>3</tlp:EmployeeID>
<tlp:AllocationID>114</tlp:AllocationID>
<tlp:TaskID>239</tlp:TaskID>
<tlp:ProjectID>26</tlp:ProjectID>
<tlp:ProjectName>LIK Template</tlp:ProjectName>
<tlp:CustomerId>343</tlp:CustomerId>
<tlp:CustomerName>Lekt Corp Inc.</tlp:CustomerName>
<tlp:IsBillable>1</tlp:IsBillable>
<tlp:ApprovedStatus>0</tlp:ApprovedStatus>
<tlp:LastModifiedBy>AL</tlp:LastModifiedBy>
</tlp:WorkUnit>
<tlp:WorkUnit ID="131">
<tlp:EmployeeID>3</tlp:EmployeeID>
<tlp:AllocationID>114</tlp:AllocationID>
<tlp:TaskID>239</tlp:TaskID>
<tlp:ProjectID>26</tlp:ProjectID>
<tlp:ProjectName>LIK Template</tlp:ProjectName>
<tlp:CustomerId>343</tlp:CustomerId>
<tlp:CustomerName>Lekt Corp Inc.</tlp:CustomerName>
<tlp:IsBillable>1</tlp:IsBillable>
<tlp:ApprovedStatus>0</tlp:ApprovedStatus>
<tlp:LastModifiedBy>AL</tlp:LastModifiedBy>
</tlp:WorkUnit>
这里是我的 ConsumeReportingApi
Class 我想遍历值的地方。
public class ConsumeReportingApi
{
private static readonly ILog Logger = LogManager.GetLogger(typeof (ConsumeReportingApi));
public static void Consume()
{
if (ServiceHandler.Instance.TryAuthenticate())
{
if (Logger.IsInfoEnabled)
{
Logger.Info("Successfully authenticated on reporting API");
}
var customersRaw = ServiceHandler.Instance.Client.GetWorkUnitsRaw(ServiceHandler.Instance.SiteCode,
ServiceHandler.Instance.ApiId,
ServiceHandler.Instance.ApiPassword,
WorkUnit.All,
Employee.All,
Allocation.All,
Task.All,
Project.All,
Department.All,
DateTime.Now.AddDays(-5).ToString(),
DateTime.Now.ToString()
);
if (customersRaw.OwnerDocument != null)
{
var namespaceManager = new XmlNamespaceManager(customersRaw.OwnerDocument.NameTable);
namespaceManager.AddNamespace("tlp", "http://www.timelog.com/XML/Schema/tlp/v4_4");
var customers = customersRaw.SelectNodes("tlp:WorkUnit", namespaceManager);
if (customers != null)
{
foreach (XmlNode customer in customers)
{
var taskId = customer.SelectSingleNode("tlp:TaskId", namespaceManager);
if (taskId != null)
{
if (Logger.IsDebugEnabled)
{
Logger.Debug("Task ID "+taskId.InnerText);
}
}
var department = customer.SelectSingleNode("tlp:ProjectName", namespaceManager);
if (department != null)
{
if (Logger.IsDebugEnabled)
{
Logger.Debug("Department ID: "+department.InnerText);
}
}
}
}
}
此时我设置的是tlp:TaskID里面的customersRaw.SelectNodes
方法。但我想得到所有其他元素 os xml 并想打印 those 值。但我不知道该怎么做。
我的主程序 class 是
public class Program
{
private static readonly ILog Logger = LogManager.GetLogger(typeof(Program));
private static readonly DirectoryInfo AppPath = new FileInfo(Assembly.GetExecutingAssembly().Location).Directory;
public static void Main(string[] args)
{
....
try
{
if (Logger.IsInfoEnabled)
{
Logger.Info("Running application");
}
// Run example classes
ConsumeReportingApi.Consume();
}
catch (Exception ex)
{
...
}
if (Logger.IsInfoEnabled)
{
Logger.Info("---");
Logger.Info("Application loop ended. Click to exit");
}
// Wait for the user to end the application.
Console.ReadKey();
}
}
}
如果你想记录所有子节点的内部文本,试试这个:
var customers = customersRaw.SelectNodes("tlp:WorkUnit", namespaceManager);
if (customers != null)
{
foreach (XmlNode customer in customers)
{
var childNodes = customer.SelectNodes("./*");
if(childNodes != null)
{
foreach(XmlNode childNode in childNodes)
{
if (Logger.IsDebugEnabled)
{
Logger.Debug(customerName.InnerText);
}
}
}
}
}
如果你想得到一个你知道名字的特定节点的内部文本,你可以使用SelectSingleNode
:
var childNode = customer.SelectSingleNode("./tlp:CustomerId", namespaceManager);
if(childNode != null)
Debug.WriteLine(childNode.InnerText);
下面的代码将 xml 工作单元解析为数据 table,然后通过 table 进行交互以获取值
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Data;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = @"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
XElement firstWorkUnit = doc.Descendants().Where(x => x.Name.LocalName == "WorkUnit").FirstOrDefault();
XNamespace ns = firstWorkUnit.GetNamespaceOfPrefix("tlp");
//create datatable
DataTable dt = new DataTable();
foreach (XElement col in firstWorkUnit.Elements())
{
dt.Columns.Add(col.Name.LocalName, typeof(string));
}
List<XElement> workUnits = doc.Descendants(ns + "WorkUnit").ToList();
foreach (XElement workUnit in workUnits)
{
DataRow newRow = dt.Rows.Add();
foreach(XElement col in workUnit.Elements())
{
newRow[col.Name.LocalName] = (string)col;
}
}
List<string> projId = dt.AsEnumerable().Select(x => x.Field<string>("ProjectID")).ToList();
}
}
}
我真的是 c# 新手。我正在创建一个项目,我需要从 XML 文件中提取数据。我可以 select 一个节点并循环遍历该元素的内部文本。但是我在 XML 文件中有几个元素。我想在一列中一次循环遍历所有元素。我怎么能这样做。我在详细解释。
这是我的 XML 文件。
<?xml version="1.0" encoding="utf-8"?>
<tlp:WorkUnits xmlns:tlp="http://www.timelog.com/XML/Schema/tlp/v4_4"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.timelog.com/XML/Schema/tlp/v4_4 http://www.timelog.com/api/xsd/WorkUnitsRaw.xsd">
<tlp:WorkUnit ID="130">
<tlp:EmployeeID>3</tlp:EmployeeID>
<tlp:AllocationID>114</tlp:AllocationID>
<tlp:TaskID>239</tlp:TaskID>
<tlp:ProjectID>26</tlp:ProjectID>
<tlp:ProjectName>LIK Template</tlp:ProjectName>
<tlp:CustomerId>343</tlp:CustomerId>
<tlp:CustomerName>Lekt Corp Inc.</tlp:CustomerName>
<tlp:IsBillable>1</tlp:IsBillable>
<tlp:ApprovedStatus>0</tlp:ApprovedStatus>
<tlp:LastModifiedBy>AL</tlp:LastModifiedBy>
</tlp:WorkUnit>
<tlp:WorkUnit ID="131">
<tlp:EmployeeID>3</tlp:EmployeeID>
<tlp:AllocationID>114</tlp:AllocationID>
<tlp:TaskID>239</tlp:TaskID>
<tlp:ProjectID>26</tlp:ProjectID>
<tlp:ProjectName>LIK Template</tlp:ProjectName>
<tlp:CustomerId>343</tlp:CustomerId>
<tlp:CustomerName>Lekt Corp Inc.</tlp:CustomerName>
<tlp:IsBillable>1</tlp:IsBillable>
<tlp:ApprovedStatus>0</tlp:ApprovedStatus>
<tlp:LastModifiedBy>AL</tlp:LastModifiedBy>
</tlp:WorkUnit>
这里是我的 ConsumeReportingApi
Class 我想遍历值的地方。
public class ConsumeReportingApi
{
private static readonly ILog Logger = LogManager.GetLogger(typeof (ConsumeReportingApi));
public static void Consume()
{
if (ServiceHandler.Instance.TryAuthenticate())
{
if (Logger.IsInfoEnabled)
{
Logger.Info("Successfully authenticated on reporting API");
}
var customersRaw = ServiceHandler.Instance.Client.GetWorkUnitsRaw(ServiceHandler.Instance.SiteCode,
ServiceHandler.Instance.ApiId,
ServiceHandler.Instance.ApiPassword,
WorkUnit.All,
Employee.All,
Allocation.All,
Task.All,
Project.All,
Department.All,
DateTime.Now.AddDays(-5).ToString(),
DateTime.Now.ToString()
);
if (customersRaw.OwnerDocument != null)
{
var namespaceManager = new XmlNamespaceManager(customersRaw.OwnerDocument.NameTable);
namespaceManager.AddNamespace("tlp", "http://www.timelog.com/XML/Schema/tlp/v4_4");
var customers = customersRaw.SelectNodes("tlp:WorkUnit", namespaceManager);
if (customers != null)
{
foreach (XmlNode customer in customers)
{
var taskId = customer.SelectSingleNode("tlp:TaskId", namespaceManager);
if (taskId != null)
{
if (Logger.IsDebugEnabled)
{
Logger.Debug("Task ID "+taskId.InnerText);
}
}
var department = customer.SelectSingleNode("tlp:ProjectName", namespaceManager);
if (department != null)
{
if (Logger.IsDebugEnabled)
{
Logger.Debug("Department ID: "+department.InnerText);
}
}
}
}
}
此时我设置的是tlp:TaskID里面的customersRaw.SelectNodes
方法。但我想得到所有其他元素 os xml 并想打印 those 值。但我不知道该怎么做。
我的主程序 class 是
public class Program
{
private static readonly ILog Logger = LogManager.GetLogger(typeof(Program));
private static readonly DirectoryInfo AppPath = new FileInfo(Assembly.GetExecutingAssembly().Location).Directory;
public static void Main(string[] args)
{
....
try
{
if (Logger.IsInfoEnabled)
{
Logger.Info("Running application");
}
// Run example classes
ConsumeReportingApi.Consume();
}
catch (Exception ex)
{
...
}
if (Logger.IsInfoEnabled)
{
Logger.Info("---");
Logger.Info("Application loop ended. Click to exit");
}
// Wait for the user to end the application.
Console.ReadKey();
}
}
}
如果你想记录所有子节点的内部文本,试试这个:
var customers = customersRaw.SelectNodes("tlp:WorkUnit", namespaceManager);
if (customers != null)
{
foreach (XmlNode customer in customers)
{
var childNodes = customer.SelectNodes("./*");
if(childNodes != null)
{
foreach(XmlNode childNode in childNodes)
{
if (Logger.IsDebugEnabled)
{
Logger.Debug(customerName.InnerText);
}
}
}
}
}
如果你想得到一个你知道名字的特定节点的内部文本,你可以使用SelectSingleNode
:
var childNode = customer.SelectSingleNode("./tlp:CustomerId", namespaceManager);
if(childNode != null)
Debug.WriteLine(childNode.InnerText);
下面的代码将 xml 工作单元解析为数据 table,然后通过 table 进行交互以获取值
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Data;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = @"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
XElement firstWorkUnit = doc.Descendants().Where(x => x.Name.LocalName == "WorkUnit").FirstOrDefault();
XNamespace ns = firstWorkUnit.GetNamespaceOfPrefix("tlp");
//create datatable
DataTable dt = new DataTable();
foreach (XElement col in firstWorkUnit.Elements())
{
dt.Columns.Add(col.Name.LocalName, typeof(string));
}
List<XElement> workUnits = doc.Descendants(ns + "WorkUnit").ToList();
foreach (XElement workUnit in workUnits)
{
DataRow newRow = dt.Rows.Add();
foreach(XElement col in workUnit.Elements())
{
newRow[col.Name.LocalName] = (string)col;
}
}
List<string> projId = dt.AsEnumerable().Select(x => x.Field<string>("ProjectID")).ToList();
}
}
}