【问题标题】:C# XmlDocument SelectNodes is not workingC# XmlDocument SelectNodes 不起作用
【发布时间】:2013-05-29 04:47:52
【问题描述】:

我想从 XML 文件中获取值,但我失败了。你能帮我指出问题吗??因为我已经非常努力地测试和谷歌搜索,但我仍然无法发现问题。

XML:

<?xml version="1.0" encoding="utf-8" ?> 
<Contacts>
  - <Contact>
    <ID>xxx</ID> 
      <AutoUpdateEnabled>false</AutoUpdateEnabled> 
      <LastChanged>2013-05-29T01:53:59.4470000Z</LastChanged> 
    - <Profiles>
        - <Personal>
              <FirstName>My First Name</FirstName> 
              <LastName>My Last Name</LastName> 
              <UniqueName>My Unique Name</UniqueName> 
              <SortName></SortName> 
              <DisplayName>My Display Name</DisplayName> 
          </Personal>
    </Profiles>
    - <Phones>
        - <Phone>
          <ID>3</ID> 
          <PhoneType>Mobile</PhoneType> 
          <Number>000-0000000</Number> 
          <IsIMEnabled>false</IsIMEnabled> 
          <IsDefault>false</IsDefault> 
          </Phone>
    </Phones>
    - <Locations>
        - <Location>
              <ID>2</ID> 
              <LocationType>Business</LocationType> 
              <CompanyName></CompanyName> 
              <IsDefault>false</IsDefault> 
          </Location>
      </Locations>
</Contact>
- <Contact>
  <ID>xxx</ID> 
  <AutoUpdateEnabled>false</AutoUpdateEnabled> 
  <LastChanged>2013-05-29T01:53:25.2670000Z</LastChanged> 
    - <Profiles>
        - <Personal>
              <FirstName>Person</FirstName> 
              <LastName>Two</LastName> 
              <UniqueName></UniqueName> 
              <SortName></SortName> 
              <DisplayName>Person Two</DisplayName> 
          </Personal>
      </Profiles>
    - <Emails>
        - <Email>
              <ID>1</ID> 
              <EmailType>Personal</EmailType> 
              <Address>MyTest@gmail.com</Address> 
              <IsIMEnabled>false</IsIMEnabled> 
              <IsDefault>true</IsDefault> 
          </Email>
      </Emails>
    - <Locations>
        - <Location>
              <ID>2</ID> 
              <LocationType>Business</LocationType> 
              <CompanyName>Testing Company</CompanyName> 
              <IsDefault>false</IsDefault> 
          </Location>
      </Locations>
    </Contact>
 </Contacts>

我的示例代码:

XmlDocument xmldoc = new XmlDocument();
xmldoc.LoadXml("TheXMLFile.xml");

xmldoc.DocumentElement.SelectNodes("contact")  // return 0 counts
xmldoc.DocumentElement.SelectNodes("/contact")  // return 0 counts
xmldoc.DocumentElement.SelectNodes("/contact")  // return 0 counts
xmldoc.DocumentElement.SelectNodes("/contacts/contact")  // return 0 counts
xmldoc.DocumentElement.SelectNodes("*")  // return 2 counts  !this works

XmlNodeList elemList = xmldoc.DocumentElement.GetElementsByTagName("contact"); // return 2 counts  !this also works
foreach (XmlNode node in elemList)
{    
    node.SelectSingleNode("Profiles")  //return ""
    node.SelectSingleNode("/Profiles")  //return ""
    node.SelectSingleNode("//Profiles")  //return ""
    node.SelectSingleNode(".//Profiles")  //return ""
}

我只想得到“名字,姓氏,电子邮件地址”,SelectNodes 函数没有像预期的那样工作......完全没有线索......请帮忙。提前致谢

【问题讨论】:

    标签: c# xml selectnodes


    【解决方案1】:

    你需要这样的东西:

    XmlDocument xmldoc = new XmlDocument();
    xmldoc.Load(@"D:\temp\contacts.xml");  // use the .Load() method - not .LoadXml() !!
    
    // get a list of all <Contact> nodes
    XmlNodeList listOfContacts = xmldoc.SelectNodes("/Contacts/Contact");
    
    // iterate over the <Contact> nodes
    foreach (XmlNode singleContact in listOfContacts)
    {
       // get the Profiles/Personal subnode
       XmlNode personalNode = singleContact.SelectSingleNode("Profiles/Personal");
    
       // get the values from the <Personal> node
       if (personalNode != null)
       {
          string firstName = personalNode.SelectSingleNode("FirstName").InnerText;
          string lastName = personalNode.SelectSingleNode("LastName").InnerText;
       }
    
       // get the <Email> nodes
       XmlNodeList emailNodes = singleContact.SelectNodes("Emails/Email");
    
       foreach (XmlNode emailNode in emailNodes)
       {
          string emailTyp = emailNode.SelectSingleNode("EmailType").InnerText;
          string emailAddress = emailNode.SelectSingleNode("Address").InnerText;
       }
    }
    

    使用这种方法,您应该能够正确读取所有需要的数据。

    【讨论】:

    • 我可以使用 foreach 循环“联系”,然后在循环内选择一封电子邮件吗??
    • @user2402624:如果您只需要一封电子邮件(可能是多封)- 是的,您可以这样做。
    • 我知道这是一篇旧文章,但据我所知,如果您想从 XMLNodeList 中选择节点(使用 Xpath 语句),LoadXML 不起作用。我得到了相同的结果 - 无论我如何安排 Xpath 都是 0。这个错误有修复吗?
    • 指向@Davor - 但他不应该只是链接到一个页面。也与 OP 的示例无关,但如果 XML 数据具有命名空间,则 SelectNodes 需要命名空间管理器才能成功。
    【解决方案2】:

    XML 标记取决于大小写,因此联系!= 联系。

    首先更改此设置。

    【讨论】:

      【解决方案3】:

      问题在于 SelectNodes 方法采用区分大小写的 XPath 表达式。

      XmlDocument xmldoc = new XmlDocument();
                  xmldoc.Load("TheXMLFile.xml");
      
                  Console.WriteLine($"Contact: {xmldoc.DocumentElement.SelectNodes("Contact").Count}"); // return 2
                  Console.WriteLine($"/Contact: {xmldoc.DocumentElement.SelectNodes("/Contact").Count}"); // return 0, and it is the expected!
                  Console.WriteLine($"//Contact: {xmldoc.DocumentElement.SelectNodes("//Contact").Count}"); // return 2
      
                  foreach (XmlNode firstName in xmldoc.DocumentElement.SelectNodes("//Profiles/Personal/FirstName"))
                  {
                      Console.WriteLine($"firstName {firstName.InnerText}");
                  }
      

      在上面的代码中,您可以看到 2 个名字,“My First Name”和“Person”。我只是将第一个字符更改为大写“联系人”->“联系人”。

      【讨论】:

        猜你喜欢
        • 2015-06-07
        • 2020-11-10
        • 2017-02-19
        • 1970-01-01
        • 2021-06-08
        • 1970-01-01
        • 2012-06-30
        • 2012-02-15
        • 1970-01-01
        相关资源
        最近更新 更多