使用具有xmlns属性的节点的XmlDocument()?

时间:2013-02-06 16:54:23

标签: c# xml xml-namespaces

我正在尝试使用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>

2 个答案:

答案 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);
}