Not logged in. · Lost password · Register
Forum: agsXMPP RSS
Avatar
artiche #1
Member since Aug 2011 · 1 post · Location: Paris, France
Group memberships: Members
Show profile · Link to this post
Subject: Error in "InnerXml" parsing for contents with only 1 level of tags
There is a problem with InnerXml property : it can't handle single tagged content : for exemple "<foo>some text</foo>" won't work and will be parsed as "<foo />". But more complex content will be ok : "<foo><bar>Some text</bar></foo>" will be parsed correctly.

An exemple to reproduce the bug :
using System;
using agsXMPP.protocol.client;
using agsXMPP;

namespace AgsXmppBugReport
{
    class Program
    {
        static void Main(string[] args)
        {
            Message m = new Message(new Jid("SomeId"))
            {
                Id = "MessageIdentifier",
                From = new Jid("SomeOtherId")
            };

            string customContent = "<someTag>Some content</someTag>";

            m.InnerXml = customContent;

            Console.WriteLine(m.ToString());
            //--> result KO : the text between the tag "someTag" wasn't correctly parsed :
            //<message xmlns="jabber:client" to="SomeId" id="MessageIdentifier" from="SomeOtherId"><someTag /></message>



            string customContent2 = "<someTag><someOtherTag>Some content</someOtherTag></someTag>";

            m.InnerXml = customContent2;

            Console.WriteLine(m.ToString());
            //--> result OK : the xml string customContent2 was entirely parsed.
            //<message xmlns="jabber:client" to="SomeId" id="MessageIdentifier" from="SomeOtherId"><someTag><someOtherTag>Some content</someOtherTag></someTag></message>

            Console.Read();
        }
    }
}

To make it work, I modified the agsXMPP.Xml.StreamParser.AddText(string text) method (I added the violet part) :

private void AddText(string text)
        {
            if (text == "")
                return;

            //Console.WriteLine("AddText:" + text);
            //Console.WriteLine(lastTOK);

            if (current != null)
            {       
                if (m_cdata)
                {
                    Node last = current.LastNode;
                    if (last != null && last.NodeType == NodeType.Cdata)
                        last.Value = last.Value + text;
                    else
                        current.AddChild(new CData(text));
                }
                else
                {
                    Node last = current.LastNode;
                    if (last != null && last.NodeType == NodeType.Text)
                        last.Value = last.Value + text;
                    else
                        current.AddChild(new Text(text));
                }
            }
            else
            {
                string s = text.Trim();
                if (!string.IsNullOrEmpty(s))
                {
                    Node last = ((Element)m_root).LastNode;
                    if (m_cdata)
                    {
                        if (last != null && last.NodeType == NodeType.Cdata)
                            last.Value = last.Value + text;
                        else
                            m_root.AddChild(new CData(text));
                    } else
                    {
                        if (last != null && last.NodeType == NodeType.Text)
                            last.Value = last.Value + text;
                        else
                            m_root.AddChild(new Text(text));
                    }
                }
            }
        }

I's a quick and dirty hack, I don't know if it's the correct way to handle that case.
Avatar
Alex #2
Member since Feb 2003 · 4328 posts · Location: Germany
Group memberships: Administrators, Members
Show profile · Link to this post
Hello,

the InnerXml is using the DOM parser which is based oen the StreamParser. The StreamParser is a Xml parser optimized for XMPP stream parsing. In XMPP we never have text in a root element which is <stream:stream .....>. This is why your case does not work.

Your fix isn't dirty, its the only way to fix this. I committed it to SVN and run some more test now to see if it breaks anything.

Alex
Close Smaller – Larger + Reply to this post:
Verification code: VeriCode Please enter the word from the image into the text field below. (Type the letters only, lower case is okay.)
Smileys: :-) ;-) :-D :-p :blush: :cool: :rolleyes: :huh: :-/ <_< :-( :'( :#: :scared: 8-( :nuts: :-O
Special characters:
Forum: agsXMPP RSS