Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. How to parse xml from a http xml response?
Forum Updated to NodeBB v4.3 + New Features

How to parse xml from a http xml response?

Scheduled Pinned Locked Moved General and Desktop
11 Posts 4 Posters 7.7k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    swhweng
    wrote on last edited by
    #1

    Hello,

    I make http call to server using QNetworkAccessManager and I get in QNetworkReply XML data of next form:
    <response>
    <status>STATUS_CODE</status>
    <item1>VALUE1</item1>
    </response>

    How can I parse QNetworkReply and get values STATUS_CODE and VALUE1?
    Does next code parse xml values :

    @void Sample::parseXml(QNetworkReply reply)
    {
    qDebug()<<reply->readAll();
    QDomDocument
    doc = new QDomDocument();
    if(doc->setContent(reply)){
    QDomElement docElem =doc->documentElement();
    QDomNode n = docElem.firstChild();
    while(!n.isNull()) {
    QDomElement e = n.toElement(); // try to convert the node to an element.
    if(!e.isNull()) {
    qDebug() << qPrintable(e.tagName())<< endl;// the node really is an element.
    }
    n = n.nextSibling();
    }
    }
    }@
    ?

    Thank you for your answer.

    1 Reply Last reply
    0
    • L Offline
      L Offline
      lgeyer
      wrote on last edited by
      #2

      [quote author="Pavel Mazniker" date="1328549678"]
      Does next code parse xml values?[/quote]

      Well, did you try it?

      Honestly if it is just the two fields use a regular expression instead. This saves you the dependency to QtXml and a full-blown DOM document each time you have to parse a reply.
      @
      QRegExp exp("s>(.*)</s.1>(.)</i");
      exp.indexIn(reply->readAll());
      if(exp.captureCount() == 2)
      {
      QString statusCode = exp.cap(1);
      QString value1 = exp.cap(2);
      }
      @

      1 Reply Last reply
      0
      • S Offline
        S Offline
        swhweng
        wrote on last edited by
        #3

        Hi Lukas,

        not yet tryed but I found the questionin another Qt forum where it wasn't answered a lot of time and I begun to code similar class.

        It is nice solution to use QRegExp in this case.Thanks.I'll try it.

        I have another question , basically when I call
        @
        networkAccessManager->get(QNetworkRequest(url));
        @
        I should await for reply ready when next signal called:
        @
        networkAccessManager->finished(QNetworkReply*);
        @
        how can I wait in code till reply?
        Can I use
        @
        while(...)
        { QApplication::processEvents() ;
        }
        @
        loop ? Any good suggestions how to wait till response process it in slot and continue processing it in the same method where networkAccessManager->get(QNetworkRequest(url)); called?

        Thanks

        Edit: some formatting fixes; Andre

        1 Reply Last reply
        0
        • L Offline
          L Offline
          lgeyer
          wrote on last edited by
          #4

          "libqxt ":http://www.libqxt.org has a "QxtSignalWaiter":http://libqxt.bitbucket.org/doc/0.6/qxtsignalwaiter.html, which is basically the loop "you've described":http://dev.libqxt.org/libqxt/src/fb22c54678d1/src/core/qxtsignalwaiter.cpp#cl-120.

          1 Reply Last reply
          0
          • S Offline
            S Offline
            swhweng
            wrote on last edited by
            #5

            thanks I'll check.
            I didn't understand yet next
            @QRegExp exp("s>(.*)</s.1>(.)</i");@

            I run that code on file it returns "" in cap(1-3).

            Could you please explain how you've constructed the expression?

            What expression should be for next xml text stream:
            @<plimus_licensing_response>
            <status>SUCCESS</status>
            <days_till_expiration>44</days_till_expiration>
            <use_count>107</use_count>
            </plimus_licensing_response>@

            Regards...

            1 Reply Last reply
            0
            • L Offline
              L Offline
              lgeyer
              wrote on last edited by
              #6

              <code>(</code> and <code>)</code> define so called capture groups, which are accessible using QRegExp::cap(). In our case it captures every character combination <code>.**</code>, limited by the (shortened) start (<statu s>) and end (</s* tatus>) element.

              So the regular expression for the second xml stream would be
              @
              QRegExp exp("<status>(.)</status>.<days_till_expiration>(.)</days_till_expiration>.<use_count>(.)</use_count>");
              @
              or shortened
              @
              QRegExp exp("s>(.
              )</s.n>(.)</d.t>(.)</u");
              @

              1 Reply Last reply
              0
              • A Offline
                A Offline
                andre
                wrote on last edited by
                #7

                I'm really not a fan of using regular expressions to parse XML. IMHO, it makes the code fragile and hard to read. If you use [[doc:QXmlStreamReader]] you don't have to link to the QtXML module. This class is in QtCore.

                1 Reply Last reply
                0
                • G Offline
                  G Offline
                  goetz
                  wrote on last edited by
                  #8

                  While one might get the raw content between the opening and closing tags using regular expressions, it is still the raw content. You need to do entity replacement manually (don't tell that doesn't happen - it will and it will bite you eventually). So adding that, bloats the code, eventually doubling functionality that's already in Qt and that's well tested.

                  PS:
                  @Pavel
                  It's usually a bad idea to ask a forum wether a code snippet will work when you didn't try it yourself yet. That will annoy otherwise helpful people and make it likely to ignore your question at all. You're supposed to do your homework. Creating a small test case for such a short snippet shouldn't be too hard.

                  http://www.catb.org/~esr/faqs/smart-questions.html

                  1 Reply Last reply
                  0
                  • L Offline
                    L Offline
                    lgeyer
                    wrote on last edited by
                    #9

                    Just for the record: regular expressions are not a replacement for full-featured XML parsing.

                    However, I would prefer them to parse two static values out of a well-defined three-liner, as long as you aware of the fact that it doesn't scale.

                    1 Reply Last reply
                    0
                    • A Offline
                      A Offline
                      andre
                      wrote on last edited by
                      #10

                      Would you mind explaining that preference? Why would you choose regexps over using real XML parsing?

                      I think something to keep in mind is, that XML is by its very nature extendable. That is: it could contain more than you took into account, and instead of that causing an error, the additional data should be ignored. Also, I think that readability of code is very important, I find regular expressions very hard to read indeed. Still, perhaps you have good reasons for this choice?

                      1 Reply Last reply
                      0
                      • L Offline
                        L Offline
                        lgeyer
                        wrote on last edited by
                        #11

                        I would not say it is a general preference, but in this specific case I would prefer a simple regular expression over QDomDocument, because it is just a waste of resources. QXmlStreamReader might be a viable option, but it still requires me to write a multitude of code just to remove some character padding around a string and an integer value (and I can hardly think of anything more extendable then a nongreedy regular expression match combined with <code>*.**</code>).

                        Yes, regular expressions should not be used as a replacement for XML parsing in general, when it comes to different encodings, a varying document structure, schema validation, optional elements and attributes and all the other gruesomeness of XML, but in this specific case ("... if it is just the two fields ..."), where two basic datatypes are paddad by some well-defined and static characters, a simple regular expression is a readable (subjective, I agree on that to a certain degree), extension-resistant single-line construct.

                        This conclusion will change if the conditions change.

                        1 Reply Last reply
                        0

                        • Login

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • Users
                        • Groups
                        • Search
                        • Get Qt Extensions
                        • Unsolved