0
<?xml version="1.0" encoding="UTF-8"?>
<message xmlns="jabber:client" to="dev_345@localhost/unityXMPP" type="chat" xml:lang="en" from="dev_272@localhost/unityXMPP">
   <archived xmlns="urn:xmpp:mam:tmp" id="1503375414608430" by="dev_345@localhost" />
   <stanza-id xmlns="urn:xmpp:sid:0" id="1503375414608430" by="dev_345@localhost" />
   <body>hi</body>
</message>

I wanted to parse the inner XML to fetch the id attribute. I have created namespace whatsoever I have found. I am able to get to, from attributes. Below is the code in c#.

string value = "<message xmlns=\"jabber:client\" to=\"dev_345@localhost/unityXMPP\" type=\"chat\" xml:lang=\"en\" from=\"dev_272@localhost/unityXMPP\"><archived xmlns=\"urn:xmpp:mam:tmp\" id=\"1503375414608430\" by=\"dev_345@localhost\" /><stanza-id xmlns=\"urn:xmpp:sid:0\" id=\"1503375414608430\" by=\"dev_345@localhost\" /><body>hi</body></message>";

    XmlDocument xmlDoc = new XmlDocument ();
    XmlNamespaceManager namespaces = new XmlNamespaceManager (xmlDoc.NameTable);
    namespaces.AddNamespace ("ns", "jabber:client");
    namespaces.AddNamespace ("ns1", "urn:xmpp:mam:tmp");
    xmlDoc.LoadXml (value);
    XmlNode messageNode = xmlDoc.SelectSingleNode ("/ns:message", namespaces);
    string sender = messageNode.Attributes ["from"].Value;
    string receiver = messageNode.Attributes ["to"].Value;
    string message = messageNode.InnerText;
    XmlNode timeStampNode = xmlDoc.SelectSingleNode ("/ns:message/ns1:archived");
    string timestamp = timeStampNode.Attributes ["id"].Value;
Dark Wizard
  • 15
  • 1
  • 4

3 Answers3

0

It's better to use the XPath, if you dont want to de-/serialize the xml into an object (Link).

Or you can use the serialization, it's a very easy way to use json or xml inside your solution (Link 1, Link 2).

E. Alex
  • 21
  • 4
  • Hey Alex, I believe the problem is coming due to namespace issues.I am aware of both the approach you have mentioned, in fact in my existing code I am already using an XPath approach. – Dark Wizard Aug 22 '17 at 06:15
  • Maybe, but you can filter all attributes or values. – E. Alex Aug 22 '17 at 06:53
0

Does this help? I used LINQ To Xml

string xmltext = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><message xmlns=\"jabber:client\" to=\"dev_345@localhost/unityXMPP\" type=\"chat\" xml:lang=\"en\" from=\"dev_272@localhost/unityXMPP\">   <archived xmlns=\"urn:xmpp:mam:tmp\" id=\"1503375414608430\" by=\"dev_345@localhost\" />   <stanza-id xmlns=\"urn:xmpp:sid:0\" id=\"1503375414608430\" by=\"dev_345@localhost\" />   <body>hi</body></message>";
var xdoc = XDocument.Parse(xmltext);
foreach (var item in xdoc.Root.Descendants())
{
    if (item.Name.LocalName == "archived")
    Console.WriteLine(item.Attribute("id").Value);                
}
Avenger789
  • 402
  • 4
  • 14
  • Thanks, It worked as expected. Just curious, if you can point out the issue in the existing code as well. Accepting this as a solution. – Dark Wizard Aug 22 '17 at 08:01
  • You have to specify the namespace when you are doing the SelectSingleNode like this - XmlNode timeStampNode = xmlDoc.SelectSingleNode("/ns:message/ns1:archived", namespaces); That will make your code work – Avenger789 Aug 22 '17 at 08:26
0

Try following xml linq to get all the data

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILENAME);

            var message = doc.Descendants().Where(x => x.Name.LocalName == "message").Select(x => new {
                to = (string)x.Attribute("to"),
                type = (string)x.Attribute("type"),
                lang = (string)x.Attributes().Where(y => y.Name.LocalName == "lang").FirstOrDefault(),
                from = (string)x.Attribute("from"),
                messages = x.Elements().Select(y => new {
                    name = y.Name.LocalName,
                    id = (string)y.Attribute("id"),
                    by = (string)y.Attribute("by"),
                    value = (string)y
                }).ToList()
            }).FirstOrDefault();
        }
    }
}
jdweng
  • 33,250
  • 2
  • 15
  • 20