我正在尝试使用XmlDocument()按节点读取每个元素的输出XML文件。
经过多次试错,我确定在我的节点上有一个xmlns属性导致没有从SelectNodes()调用返回任何节点。不知道为什么。
由于我无法更改输出格式且无法访问实际的命名空间,因此我有哪些方法可以解决此问题?
另外,我有一些有子节点的元素。在循环遍历XML文件时如何访问这些文件? I.E.,我需要解密CipherValue元素,但不知道如何访问这个节点呢?
以下示例:
doc.Load(@"test.xml");
XmlNodeList logEntryNodeList = doc.SelectNodes("/Logs/LogEntry");
Console.WriteLine("Nodes = {0}", logEntryNodeList.Count);
foreach (XmlNode xn in logEntryNodeList)
{
string dateTime = xn["DateTime"].InnerText;
string sequence = xn["Sequence"].InnerText;
string appId = xn["AppID"].InnerText;
Console.WriteLine("{0} {1} {2}", dateTime, sequence, appId);
}
示例XML如下所示:
<Logs>
<LogEntry Version="1.5" PackageVersion="10.10.0.10" xmlns="http://private.com">
<DateTime>2013-02-04T14:05:42.912349-06:00</DateTime>
<Sequence>5058</Sequence>
<AppID>TEST123</AppID>
<StatusDesc>
<EncryptedData>
<CipherData xmlns="http://www.w3.org/2001/04/xmlenc#">
<CipherValue>---ENCRYPTED DATA BASE64---</CipherValue>
</CipherData>
</EncryptedData>
</StatusDesc>
<Severity>Detail</Severity>
</LogEntry>
<LogEntry Version="1.5" PackageVersion="10.10.0.10" xmlns="http://private.com">
<DateTime>2013-02-04T14:05:42.912350-06:00</DateTime>
<Sequence>5059</Sequence>
<AppID>TEST123</AppID>
<StatusDesc>
<EncryptedData>
<CipherData xmlns="http://www.w3.org/2001/04/xmlenc#">
<CipherValue>---ENCRYPTED DATA BASE64---</CipherValue>
</CipherData>
</EncryptedData>
</StatusDesc>
<Severity>Detail</Severity>
</LogEntry>
</Logs>
答案 0 :(得分:1)
经过多次试错,我确定在我的节点上有一个xmlns属性导致没有从SelectNodes()调用返回任何节点。不知道为什么。
xmlns
属性有效地更改了元素中的默认命名空间,包括该元素本身。因此,LogEntry
元素的命名空间为"http://private.com"
。您需要在XPath查询中适当地包含它,可能是通过XmlNamespaceManager
。
(如果您可以使用LINQ to XML,那么 更容易使用命名空间。)
答案 1 :(得分:0)
你可以使用Linq到Xml(如Jon所述)。这是代码,它根据命名空间解析您的xml文件。结果是一个强类型的匿名对象序列(即Date属性的类型为DateTime,Sequence是整数,AppID是一个字符串):
XDocument xdoc = XDocument.Load("test.xml");
XNamespace ns = "http://private.com";
var entries = xdoc.Descendants("Logs")
.Elements(ns + "LogEntry")
.Select(e => new {
Date = (DateTime)e.Element(ns + "DateTime"),
Sequence = (int)e.Element(ns + "Sequence"),
AppID = (string)e.Element(ns + "AppID")
}).ToList();
Console.WriteLine("Entries count = {0}", entries.Count);
foreach (var entry in entries)
{
Console.WriteLine("{0}\t{1} {2}",
entry.Date, entry.Sequence, entry.AppID);
}