Results 1 to 9 of 9

Thread: reading XML node and sub nodes

  1. #1
    Join Date
    Jan 2006
    Posts
    368
    Thanks
    14
    Thanked 18 Times in 17 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default reading XML node and sub nodes

    Hi all,

    I need to parse an XML file. When a specific node, is found, I need to get the exact test inside that tag, not only the "xml text".

    Example:
    Qt Code:
    1. <root>
    2. <a>11111</a>
    3. <a><b>test 123</b></a>
    4. </root>
    To copy to clipboard, switch view to plain text mode 

    In this XML I need to be able to get: "1111" and "<b>test 123</b>".

    I am using this code in Qt5:
    Qt Code:
    1. void test1() {
    2. QString rawXML =
    3. "<root>"
    4. " <a>11111</a>"
    5. " <a><b>test 123</b></a>"
    6. "</root>";
    7. QXmlStreamReader xml(rawXML);
    8. QStringRef s;
    9.  
    10. xml.readNextStartElement();
    11. s = xml.name();
    12. if (s!="root") {
    13. return;
    14. }
    15.  
    16. while (!xml.atEnd()) {
    17. xml.readNextStartElement();
    18. s = xml.name();
    19. if (s!="a") {
    20. break;
    21. }
    22.  
    23. QString ss = xml.readElementText(QXmlStreamReader::IncludeChildElements);
    24. qDebug("%s", qPrintable(ss));
    25. }
    26. }
    To copy to clipboard, switch view to plain text mode 

    This is not working as I expect. I am getting "test 123" and not "<b>test 123</b>".

    What is the best approach to handle this situation? How can I parse the XML and getting the desired result?

    xml-test1.cpp

    EDIT: similar stackoverflow question: http://stackoverflow.com/questions/5...ing-html-in-qt
    Last edited by elcuco; 15th August 2014 at 20:39.

  2. #2
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,593
    Thanks
    13
    Thanked 1,587 Times in 1,516 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: reading XML node and sub nodes

    Take a look at the tokenString() function. You may be able to construct the result as you go through the start, text, and end tokens of the <b> element.

  3. #3
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,420
    Thanks
    37
    Thanked 1,545 Times in 1,495 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: reading XML node and sub nodes

    Alternatively use QDomDocument for parsing, QDomDocument::elementsByTagName to get all the <a> tags, then call QDomNode::save() on all their children.

    Cheers,
    _

  4. #4
    Join Date
    Jan 2006
    Posts
    368
    Thanks
    14
    Thanked 18 Times in 17 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: reading XML node and sub nodes

    Another solution that does not work:

    Qt Code:
    1. QByteArray ba(rawXML);
    2. QBuffer bytes;
    3.  
    4. bytes.setBuffer(&ba);
    5. bytes.open(QIODevice::ReadOnly);
    6. QXmlStreamReader xml(&bytes);
    7. ...
    8. QIODevice *device = xml.device();
    9. pstart = device->pos();
    10. QString ss = xml.readElementText(QXmlStreamReader::IncludeChildElements);
    11. pend = device->pos();
    12.  
    13. char line[100];
    14. int len = pend-pstart;
    15. device->seek(pstart);
    16. device->read(line, len);
    17. device->seek(pend);
    To copy to clipboard, switch view to plain text mode 

    This is because it seems that seems that QXmlStreamReader will buffer my whole data in advance. .. so "pos()" will always return the last byte in the raw data.

  5. #5
    Join Date
    Jan 2006
    Posts
    368
    Thanks
    14
    Thanked 18 Times in 17 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: reading XML node and sub nodes

    2nd attempt, using QDomDocument:

    Qt Code:
    1. void test2() {
    2. const char* rawXML =
    3. "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
    4. "<root>"
    5. " <a>11111</a>"
    6. " <a><b>test 123</b></a>"
    7. "</root>";
    8. QDomDocument xml("rawXML");
    9. QByteArray ba(rawXML);
    10. xml.setContent(ba);
    11.  
    12. QDomElement rootElement = xml.documentElement();
    13. qDebug("root element has %d childs", rootElement.childNodes().count());
    14. qDebug("root element is %s ", qPrintable(rootElement.nodeName()) );
    15.  
    16. QDomNodeList a = rootElement.elementsByTagName("a");
    17. for (int i=0; i< a.length(); i ++) {
    18. QString aContent;
    19. QTextStream ts(&aContent);
    20. a.at(i).save(ts,0);
    21. qDebug("- [%s]", qPrintable(aContent));
    22. QDomNode d = a.at(i);
    23. }
    24. }
    To copy to clipboard, switch view to plain text mode 

    Now, I get not only the content, but the tags as well. This is the output:

    Qt Code:
    1. root element has 2 childs
    2. root element is root
    3. - [<a>11111</a>
    4. ]
    5. - [<a>
    6. <b>test 123</b>
    7. </a>
    8. ]
    To copy to clipboard, switch view to plain text mode 

    I assume I can trim the leading
    <a>
    and ending
    </a>\n
    , but this is at the same level of ugliness I am trying to avoid.

    Any other idea?

    EDIT:

    I should be testing more before testing. anda_skoa, I re-read your post and changed:

    Qt Code:
    1. const char* rawXML = "<root><a>11111</a><a><b>test 123</b></a></root>";
    2.  
    3. for (int i=0; i< alist.length(); i ++) {
    4. QDomNode a = alist.at(i);
    5. QString aContent;
    6. QTextStream ts(&aContent);
    7. a.firstChild().save(ts,0);
    8. qDebug("- [%s]", qPrintable(aContent));
    9. }
    To copy to clipboard, switch view to plain text mode 

    Which is better:
    - [11111]
    - [<b>test 123</b>
    ]
    Still, I get an extra newline after then
    Qt Code:
    1. </b>
    To copy to clipboard, switch view to plain text mode 
    which is bad for me... but its much better then before. It seems that QDomDocument is adding extra newlines when parsing. Am I correct? How can I disable this "feature"?
    Last edited by elcuco; 17th August 2014 at 18:01.

  6. #6
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,420
    Thanks
    37
    Thanked 1,545 Times in 1,495 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: reading XML node and sub nodes

    Does the newline matter? it is still the same XML content, no?

    One other thing you could look into is XQuery, Qt has a module for that as well (called Qt XML patterns)

    Cheers,
    _

  7. #7
    Join Date
    Jan 2006
    Posts
    368
    Thanks
    14
    Thanked 18 Times in 17 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: reading XML node and sub nodes

    I modified the XML source to be in a single line (see last example). The newline is important, but since it can be part of the input (I think it needs to be escaped, so it may be possible to filter out). Still bugs me as it feels like Qt is doing extra work behind my back.

    Yes, XmlPatterns is another option... I was looking into it, but as I know nothing about it, I was hoping someone would give me the one-liner I am looking for...

  8. #8
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,420
    Thanks
    37
    Thanked 1,545 Times in 1,495 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: reading XML node and sub nodes

    Hmm, I am not sure the newline at this point (after an end tag) is relevant as far as XML goes.

    Cheers,
    _

  9. #9
    Join Date
    Jan 2006
    Posts
    368
    Thanks
    14
    Thanked 18 Times in 17 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: reading XML node and sub nodes

    Quote Originally Posted by anda_skoa View Post
    Hmm, I am not sure the newline at this point (after an end tag) is relevant as far as XML goes.

    Cheers,
    _
    In theory you are right.
    In practice, I am paring XMLs that contain data which (once) was a user input, and thus I need to store the exact that the user wrote.

    Note to self:
    If you ever get into problems ... UUENCODE or base64 that &^%&^% text.... unfortunately this time the format is pre-defined for me.

Similar Threads

  1. Designing a Node Editor (Hint: Blender Node Editor)
    By Mind Calamity in forum Qt Programming
    Replies: 4
    Last Post: 5th October 2011, 16:22
  2. elastic nodes example
    By sajis997 in forum Newbie
    Replies: 2
    Last Post: 3rd August 2011, 15:08
  3. XML: accessing deep nodes
    By mentalmushroom in forum Qt Programming
    Replies: 7
    Last Post: 9th June 2011, 06:56
  4. how to justfy a node is leaf node or not
    By weixj2003ld in forum Qt Programming
    Replies: 4
    Last Post: 9th April 2009, 07:40
  5. [QT4] QTreeView and expandable nodes
    By KShots in forum Qt Programming
    Replies: 3
    Last Post: 17th March 2006, 16:52

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.