views:

104

answers:

4

I have the following XML:

<iq xmlns="jabber:client" to="[email protected]/agsXMPP" xml:lang="en" id="sub23" from="search.google.com" type="result">
    <pubsub xmlns="http://jabber.org/protocol/pubsub"&gt;
        <subscription subscription="subscribed" subid="5077774B57777BD77770" node="search" jid="[email protected]/agsXMPP" />
    </pubsub>
</iq>

I've tried parsing with linq to sql, but it doesn't seem to understand that these are different nodes. It groups the whole iq into a single element.

Can anyone help in parsing this using XML?

The data I want to get is the subid="5077774B57777BD77770" and the id="sub23"

Thanks!

Edit:

Here's the code I have, tried doing it in two ways:

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")
                       };

and

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

Read this for an explanation and a complete code example how to evaluate an XPath expression that contains location steps with nodes whose names are in a default namespace and are unprefixed in the XML document..

Dimitre Novatchev
A: 

I concur with Dimitre - the "empty" xmlns namespace at the top is probably causing the problem. I sometimes strip these out with a regex if they're not used, otherwise play around with XmlNameSpaceManager as described

Chris Webb
I hope that the confusion of ideas that would lead you to describe a namespace declaration with no abbreviation as "empty" is not as deep as it appears. Removing namespace declarations from the source XML is like replacing a fuse with a penny: just because your lights come back on doesn't mean that everything's fine.
Robert Rossney
+3  A: 

As Dimitre pointed out, you have a namespace issue. This will work:

    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();
        }
    }
}
hjd
Thanks, that works great. Didn't realize you can just add your own "ns1", "ns2" for namespaces that don't have a prefix that's used.
rksprst
hjd: Good answer. But, why don't you select the attributes with XPath?
Alejandro
Good point, could just as easily have done: `string ID = doc.SelectSingleNode("/ns1:iq/@id", namespaces).Value;`
hjd
+1  A: 

I'm not sure if this is what you're after, but it works:

XNamespace jabber = "jabber:client";
XNamespace pubsub = "http://jabber.org/protocol/pubsub";

string xmltext = "<iq xmlns=\"jabber:client\" to=\"[email protected]/agsXMPP\" xml:lang=\"en\" id=\"sub23\" from=\"search.google.com\" type=\"result\">\n"
    + "<pubsub xmlns=\"http://jabber.org/protocol/pubsub\"&gt;\n"
    + "<subscription subscription=\"subscribed\" subid=\"5077774B57777BD77770\" node=\"search\" jid=\"[email protected]/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);
Foole