尝试从 XML 检索节点时为空值

Null value when trying to retrieve a node from XML

我需要读取和更新 CollectionPlan 的值 -> CheckpointOptions -> ThreadCheckpoints -> Mode 从下面的xml

<?xml version="1.0" encoding="utf-8"?>
<CollectionPlan xmlns="urn:schemas-microsoft-com:visualstudio:tracelog">
  <StartupInfo>
    <LogFileName>
    </LogFileName>
    <LogFileDirectory>C:\LogFiles</LogFileDirectory>
    <MaximumLogFileSize>16384</MaximumLogFileSize>
  </StartupInfo>
  <CheckpointOptions>
    <ThreadCheckpoints>
      <Mode>FixedEventRate</Mode>
      <StartRate>30000</StartRate>
    </ThreadCheckpoints>
    <NotifyPointCheckpoints>
      <Mode>FixedEventRate</Mode>
      <StartRate>1000</StartRate>
    </NotifyPointCheckpoints>
  </CheckpointOptions>
  <!-- many other nodes -->
 </CollectionPlan>

为此,我有以下代码。

XmlDocument doc = new XmlDocument();
XmlNamespaceManager manager = new XmlNamespaceManager(doc.NameTable);
manager.AddNamespace("urn:", "schemas-microsoft-com:visualstudio:tracelog");
doc.Load(@"c:\myXml.xml");
var aNodes = doc.SelectSingleNode("CollectionPlan/CheckpointOptions/ThreadCheckpoints/Mode", manager);

但是 aNodes 为 NULL。我这里哪里不对?

我认为你需要使用:

manager.AddNamespace("tlog", "urn:schemas-microsoft-com:visualstudio:tracelog");

urn 是协议,不是前缀。它是名称空间规范的一部分,因此您需要将其放在那里。

你有几个问题:

  1. 您需要使用出现在 XML 中的正确根命名空间。是"urn:schemas-microsoft-com:visualstudio:tracelog".

  2. 在对 AddNamespace 的调用中,不要在前缀字符串中使用 ::字符不是命名空间前缀的一部分,它用于在解析查询字符串时将前缀与元素本地名称分开。

  3. 在对 SelectSingleNode 的调用中,您需要在查询中为您的节点本地名称加上您使用命名空间管理器定义的命名空间前缀 "urn:" 作为前缀,因为XML 您要搜索的节点在相应的命名空间中。

因此以下应该有效:

XmlDocument doc = new XmlDocument();
XmlNamespaceManager manager = new XmlNamespaceManager(doc.NameTable);
manager.AddNamespace("urn", "urn:schemas-microsoft-com:visualstudio:tracelog");
doc.Load(@"c:\myXml.xml")
var aNodes = doc.SelectSingleNode("urn:CollectionPlan/urn:CheckpointOptions/urn:ThreadCheckpoints/urn:Mode", manager);

原型fiddle.