【问题标题】:C# Xml Value always getting nullC# Xml 值总是为空
【发布时间】:2011-06-06 13:48:23
【问题描述】:

我的 Resources.xmltest 中有以下 Xml:

<?xml version="1.0" encoding="utf-8" ?>   
<Response xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://DFISofft.com/SmartPayments/">
    <Result>0</Result>
    <Message>Pending</Message>
    <PNRef>222131</PNRef>
    <ExtData>InvNum=123</ExtData>   
 </Response>

我尝试了几种方法来从中获取值,Result、Message、PNRef、ExtData,但我没有运气。我总是得到 NodePath 的空值,所以它永远不会进入循环:

  var XmlDoc = new XmlDocument();

  XmlDoc.LoadXml(Resources.xmltest);
  XmlElement NodePath = (XmlElement) XmlDoc.SelectSingleNode("/Response");

  while (NodePath != null)
  {
    foreach (XmlNode Xml_Node in NodePath)
    {
      Console.WriteLine(Xml_Node.Name + " " + Xml_Node.InnerText);
    }
  }

我试过了:

  XmlNode node3 = XmlDoc.SelectSingleNode("PNRef");
  Console.WriteLine(node3.Value);

  Console.WriteLine(XmlDoc.InnerXml);

  var tst = XmlDoc.GetElementsByTagName("PNRef");
  Console.WriteLine(tst);

还有这个:

  NodePath = (XmlElement) XmlDoc.SelectSingleNode("/Response");

  if (NodePath != null)
  {
    foreach (XmlNode node in NodePath)
    {
      Console.WriteLine("NodeName: " + Xml_NodeX.Name);
      Console.WriteLine("NodeValue: " + node.InnerText);
    }
   }

显然,我没有读取/写入 xml。我已经使用 DataSets 完成了它,但它们会为您完成所有工作。

有人能指出我正确的方向吗?我做这个的时间比我应该做的要长。

谢谢!

【问题讨论】:

  • 感谢大家快速而精彩的回答!

标签: c# xml parsing


【解决方案1】:

您的 XML 有一个 XML 命名空间,而您没有注意到它:

<Response xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
          xmlns="http://DFISofft.com/SmartPayments/">
          ******************************************

从这个 XML 中选择时,您需要使用那个 XML 命名空间!

您没有考虑文档上的 XML 命名空间 (xmlns="http://nts-de-osm1-pxc/webservices/")!

试试这个:

 var XmlDoc = new XmlDocument();

 // setup the XML namespace manager
 XmlNamespaceManager mgr = new XmlNamespaceManager(XmlDoc.NameTable);

 // add the relevant namespaces to the XML namespace manager
 mgr.AddNamespace("ns", "http://DFISofft.com/SmartPayments/"); 

 XmlDoc.LoadXml(Resources.xmltest);

 // **USE** the XML anemspace in your XPath !!
 XmlElement NodePath = (XmlElement) XmlDoc.SelectSingleNode("/ns:Response");

  while (NodePath != null)
  {
    foreach (XmlNode Xml_Node in NodePath)
    {
      Console.WriteLine(Xml_Node.Name + " " + Xml_Node.InnerText);
    }
  }

【讨论】:

    【解决方案2】:

    问题在于您的 XPath 查询,它没有指定名称空间 - 尽管您的文档在“http://DFISofft.com/SmartPayments/”名称空间中只有一个 Response 元素。 PNRef 元素也是如此。

    如果我实际上想尽可能使用命名空间,我个人会使用 LINQ to XML。例如:

    XNamespace ns = "http://DFISofft.com/SmartPayments/";
    XDocument doc = XDocument.Load(filename);
    
    foreach (var element in doc.Descendants(ns + "PNRef"))
    {
        // Use element here
    }
    

    如您所见,LINQ to XML 让命名空间的使用变得非常容易——但它当然需要 .NET 3.5 或更高版本。如果我必须使用 .NET 2.0,我会使用 XmlNamespaceManager 或手动迭代并检查本地名称,而不是使用 XPath。

    【讨论】:

      【解决方案3】:

      那是因为节点不叫响应;您需要考虑命名空间:

      var XmlDoc = new XmlDocument();
      var nsmgr = new XmlNamespaceManager(XmlDoc.NameTable);
      nsmgr.AddNamespace("x", "http://DFISofft.com/SmartPayments/");
      XmlDoc.LoadXml(yourXml);
      XmlElement NodePath = (XmlElement)XmlDoc.SelectSingleNode("/x:Response", nsmgr);
      

      【讨论】:

        【解决方案4】:

        供以后参考...

        Bubba Soft 这个网站有一个很棒的免费工具来构建 XPath 表达式 (XPath Builder)。

        【讨论】:

          【解决方案5】:

          这是因为您正在使用 SelectSingleNode 的重载,它假定一个空的命名空间。由于您有一个默认命名空间,因此您需要使用采用 XmlNamespaceManager 的版本。 See this article for more info.

          来自文档:

          如果 XPath 表达式不包含前缀,则假定名称空间 URI 是空名称空间。如果您的 XML 包含默认命名空间,您仍必须向 XmlNamespaceManager 添加前缀和命名空间 URI;否则,您将无法选择节点。有关详细信息,请参阅使用 XPath 导航选择节点。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-02-07
            • 2019-12-05
            • 2021-07-03
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多