【问题标题】:How to get the xml node value in string如何获取字符串中的xml节点值
【发布时间】:2013-07-11 09:46:11
【问题描述】:

我尝试了下面的代码来获取特定节点的值,但是在加载 xml 时抛出了这个异常:

例外:

根级别的数据无效。第 1 行,位置 1。

XML

<?xml version="1.0"?>
<Data xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <Date>11-07-2013</Date> 
    <Start_Time>PM 01:37:11</Start_Time> 
    <End_Time>PM 01:37:14</End_Time> 
    <Total_Time>00:00:03</Total_Time> 
    <Interval_Time/>
    <Worked_Time>00:00:03</Worked_Time> 
    <Short_Fall>08:29:57</Short_Fall> 
    <Gain_Time>00:00:00</Gain_Time> 
</Data>

C#:

XmlDocument xml = new XmlDocument();
filePath = @"D:\Work_Time_Calculator\10-07-2013.xml";
xml.LoadXml(filePath);  // Exception occurs here 
XmlNode node = xml.SelectSingleNode("/Data[@*]/Short_Fall");
string id = node["Short_Fall"].InnerText;

修改后的代码

C#:

XmlDocument xml = new XmlDocument();
filePath = @"D:\Work_Time_Calculator\10-07-2013.xml";
xml.Load(filePath);  
XmlNode node = xml.SelectSingleNode("/Data[@*]/Short_Fall");
string id = node["Short_Fall"].InnerText; // Exception occurs here ("Object reference not set to an instance of an object.")

【问题讨论】:

标签: c# .net xml


【解决方案1】:

你代码中的问题是xml.LoadXml(filePath);

LoadXml 方法将参数作为 xml 数据 而不是 xml 文件路径

试试这个代码

   string xmlFile = File.ReadAllText(@"D:\Work_Time_Calculator\10-07-2013.xml");
                XmlDocument xmldoc = new XmlDocument();
                xmldoc.LoadXml(xmlFile);
                XmlNodeList nodeList = xmldoc.GetElementsByTagName("Short_Fall");
                string Short_Fall=string.Empty;
                foreach (XmlNode node in nodeList)
                {
                    Short_Fall = node.InnerText;
                }

编辑

看到你的问题的最后编辑我找到了解决方案,

只需替换以下两行

XmlNode node = xml.SelectSingleNode("/Data[@*]/Short_Fall");
string id = node["Short_Fall"].InnerText; // Exception occurs here ("Object reference not set to an instance of an object.")

string id = xml.SelectSingleNode("Data/Short_Fall").InnerText;

它应该可以解决您的问题,或者您可以使用我之前提供的解决方案。

【讨论】:

    【解决方案2】:

    您应该使用.Load 而不是.LoadXML

    MSDN Link

    “LoadXml 方法用于直接加载 XML 字符串。您想改用 Load 方法。”

    参考:Link

    【讨论】:

    • 我使用 Load 方法现在没有抛出异常,但“对象引用未设置为对象的实例。”在行字符串 id = node["Short_Fall"].InnerText; 处抛出
    • 我认为这是因为您已经在 Short_Fall 中,就像您在上一行中所做的那样 xml.SelectSingleNode("/Data[@*]/Short_Fall");
    • 那么如何获取特定的节点值
    • 直接尝试node.InnerText
    【解决方案3】:
    XmlDocument d = new XmlDocument();
    d.Load(@"D:\Work_Time_Calculator\10-07-2013.xml");
    XmlNodeList n = d.GetElementsByTagName("Short_Fall");
    if(n != null) {
        Console.WriteLine(n[0].InnerText); //Will output '08:29:57'
    }
    
    or you could wrap in foreach loop to print each value
    
    XmlDocument d = new XmlDocument();
    d.Load(@"D:\Work_Time_Calculator\10-07-2013.xml");
    XmlNodeList n = d.GetElementsByTagName("Short_Fall");
    if(n != null) {
        foreach(XmlNode curr in n) {
            Console.WriteLine(curr.InnerText);
        }
    }
    

    【讨论】:

      【解决方案4】:

      这些帖子帮助我解决了一些问题,我在创建 CLR 存储过程时遇到了针对 Infor M3 API 的 Restful API 调用。

      这些 API 的 XML 结果如下所示:

      miResult xmlns="http://lawson.com/m3/miaccess">
          <Program>MMS200MI</Program>
          <Transaction>Get</Transaction>
          <Metadata>...</Metadata>
          <MIRecord>
              <RowIndex>0</RowIndex>
              <NameValue>
                  <Name>STAT</Name>
                  <Value>20</Value>
              </NameValue>
              <NameValue>
                  <Name>ITNO</Name>
                  <Value>ITEM123</Value>
              </NameValue>
              <NameValue>
                  <Name>ITDS</Name>
                  <Value>ITEM DESCRIPTION 123 </Value>
              </NameValue>
      ...
      

      用于完成从 API 中列出结果集的 CLR C# 代码的工作方式如下所示:

      using System;
      using System.Data;
      using System.Data.SqlClient;
      using System.Data.SqlTypes;
      using System.IO;
      using System.Net;
      using System.Text;
      using System.Xml;
      using Microsoft.SqlServer.Server;
      
      public partial class StoredProcedures
      {
          [Microsoft.SqlServer.Server.SqlProcedure]
          public static void CallM3API_Test1()
          {
              SqlPipe pipe_msg = SqlContext.Pipe;
              try
              {
                  HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://M3Server.domain.com:12345/m3api-rest/execute/MMS200MI/Get?ITNO=ITEM123");
      
                  request.Method = "Get";
                  request.ContentLength = 0;
      
                  request.Credentials = new NetworkCredential("myUserID@domain.com", "MyPassword");
                  request.ContentType = "application/xml";
                  request.Accept = "application/xml";
      
                  using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                  {
                          using (Stream receiveStream = response.GetResponseStream())
                          {
                              using (StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8))
                              {
                                  string strContent = readStream.ReadToEnd();
                                  XmlDocument xdoc = new XmlDocument();
                                  xdoc.LoadXml(strContent);
                                  try
                                  {
                                      SqlPipe pipe = SqlContext.Pipe;
      
                                      //Define Output Columns and Max Length of each Column in the Resultset    
                                      SqlMetaData[] cols = new SqlMetaData[2];
                                      cols[0] = new SqlMetaData("Name", SqlDbType.NVarChar, 50);
                                      cols[1] = new SqlMetaData("Value", SqlDbType.NVarChar, 120);
                                      SqlDataRecord record = new SqlDataRecord(cols);
      
                                      pipe.SendResultsStart(record);
      
                                      XmlNodeList nodeList = xdoc.GetElementsByTagName("NameValue");
                                      //List ALL Output Names + Values
                                      foreach (XmlNode nodeRes in nodeList)
                                      {
                                          record.SetSqlString(0, nodeRes["Name"].InnerText);
                                          record.SetSqlString(1, nodeRes["Value"].InnerText);
      
                                          pipe.SendResultsRow(record);
                                      }
      
                                      pipe.SendResultsEnd();
                                  }
                                  catch (Exception ex)
                                  {
                                      SqlContext.Pipe.Send("Error (readStream): " + ex.Message);
                                  }
                              }
                          }
                  }
              }
              catch (Exception ex)
              {
                  SqlContext.Pipe.Send("Error (CallM3API_Test1): " + ex.Message);
      
              }
          }
      }
      

      希望这会有所帮助。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-02-20
        • 1970-01-01
        相关资源
        最近更新 更多