【问题标题】:Help in parsing XML, simple string - but I can't seem to parse it帮助解析 XML,简单的字符串 - 但我似乎无法解析它
【发布时间】:2010-10-18 00:46:36
【问题描述】:

我有以下 XML:

<iq xmlns="jabber:client" to="39850777771287777738178727@guest.google.com/agsXMPP" xml:lang="en" id="sub23" from="search.google.com" type="result">
    <pubsub xmlns="http://jabber.org/protocol/pubsub">
        <subscription subscription="subscribed" subid="5077774B57777BD77770" node="search" jid="39850777771287777738178727@guest.google.com/agsXMPP" />
    </pubsub>
</iq>

我试过用 linq to sql 解析,但似乎不明白这些是不同的节点。它将整个 iq 组合成一个元素。

任何人都可以帮助使用 XML 解析这个吗?

我要获取的数据是 subid="5077774B57777BD77770" 和 id="sub23"

谢谢!

编辑:

这是我的代码,尝试了两种方式:

XDocument doc = XDocument.Parse("<xml>" + iq.ToString() + "</xml>");
        var results = from feed in doc.Elements("xml")
                       select new
                       {
                           Id = (string)feed.Element("iq").Attribute("id"),
                           Subid = (string)feed.Element("iq").Element("pubsub").Element("subscription").Attribute("subid")
                       };

                var doc = new System.Xml.XmlDocument();
            doc.LoadXml(iq.ToString());
            var searchId = doc.Attributes["id"];
            var subid = doc.SelectSingleNode("/pubsub/subscription").Attributes["subid"];

【问题讨论】:

  • 请出示您的代码
  • @Hogan 刚刚添加了我上面的代码
  • 好问题,+1。请参阅我的答案,以获取有关在 XML 文档具有默认命名空间时如何构造 XPath 表达式的解释和完整代码示例的参考。

标签: c# xml xpath xml-serialization xml-namespaces


【解决方案1】:

正如 Dimitre 所指出的,您遇到了命名空间问题。这将起作用:

    using System;
using System.Xml;

namespace XMLTest
{
    class Program
    {
        static void Main(string[] args)
        {
            XmlDocument doc = new XmlDocument();
             XmlNamespaceManager namespaces = new XmlNamespaceManager(doc.NameTable);
            namespaces.AddNamespace("ns1", "jabber:client");
            namespaces.AddNamespace("ns2", "http://jabber.org/protocol/pubsub");
            doc.Load("xmltest.xml");

            XmlNode iqNode = doc.SelectSingleNode("/ns1:iq", namespaces);
            string ID = iqNode.Attributes["id"].Value;
            Console.WriteLine(ID);

            XmlNode subscriptionNode = doc.SelectSingleNode("/ns1:iq/ns2:pubsub/ns2:subscription", namespaces);
            string subID = subscriptionNode.Attributes["subid"].Value;
            Console.WriteLine(subID);

            Console.ReadLine();
        }
    }
}

【讨论】:

  • 谢谢,效果很好。没有意识到您可以为没有使用前缀的命名空间添加自己的“ns1”、“ns2”。
  • hjd:很好的答案。但是,为什么不用 XPath 选择属性呢?
  • 好点,本可以轻松完成:string ID = doc.SelectSingleNode("/ns1:iq/@id", namespaces).Value;
【解决方案2】:

阅读 this 以获取解释和完整的代码示例如何评估包含位置步骤的 XPath 表达式,其中节点的名称位于默认命名空间中且在 XML 文档中没有前缀。

【讨论】:

    【解决方案3】:

    我不确定这是否是您所追求的,但它有效:

    XNamespace jabber = "jabber:client";
    XNamespace pubsub = "http://jabber.org/protocol/pubsub";
    
    string xmltext = "<iq xmlns=\"jabber:client\" to=\"39850777771287777738178727@guest.google.com/agsXMPP\" xml:lang=\"en\" id=\"sub23\" from=\"search.google.com\" type=\"result\">\n"
        + "<pubsub xmlns=\"http://jabber.org/protocol/pubsub\">\n"
        + "<subscription subscription=\"subscribed\" subid=\"5077774B57777BD77770\" node=\"search\" jid=\"39850777771287777738178727@guest.google.com/agsXMPP\" />\n"
        + "</pubsub>\n"
        + "</iq>";
    
    XDocument xdoc = XDocument.Parse(xmltext);
    
    var iqelem = xdoc.Element(jabber + "iq");
    var id = iqelem.Attribute("id").Value;
    
    var subselem = iqelem.Element(pubsub + "pubsub").Element(pubsub + "subscription");
    var subid = subselem.Attribute("subid").Value;
    
    Console.WriteLine("SubId = {0}\nId={1}", subid, id);
    

    【讨论】:

      【解决方案4】:

      我同意 Dimitre - 顶部的“空”xmlns 命名空间可能会导致问题。如果不使用它们,我有时会用正则表达式将它们去掉,否则按照描述使用 XmlNameSpaceManager

      【讨论】:

      • 我希望导致您将没有缩写的命名空间声明描述为“空”的概念混乱并不像看起来那么深刻。从源 XML 中删除命名空间声明就像用一分钱替换保险丝:仅仅因为您的灯重新亮起并不意味着一切都很好。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-18
      相关资源
      最近更新 更多