Results 1 to 3 of 3

Thread: Having trouble with direct child nodes using QtXml

  1. #1
    Join Date
    Jul 2008
    Qt products

    Default Having trouble with direct child nodes using QtXml

    I've got an XML file that I'm trying to parse using QtXml in v4.3.3. It's being used to describe a hierarchy of related, as well as very similar, objects used in a schematic-like diagram tool. The actual file I need to get working is considered proprietary to our company, so I've made a test version that I can post (see below) that displays the same issue. If you'll notice, with the way this file is laid out, it lends itself nicely to recursive parsing.

    What I'm running into is that the QDomNodeList being returned from QDomNode::childNodes() is not a list of the direct child nodes, as the Qt Assistant says it should be, but rather a list of all child nodes. A little further reading revealed the QDomElement::elementsByTagName(QString) function. When I tried this out and passed it "Element" starting at the <Container name="L1Container" autoAdd="true"> line, I expected to see only one child. Instead I got three--which would be all of the Element tags beneath the <Container>. Am I just misunderstanding the phrase "direct child nodes?" Because, I've done similar parsing with other packages and did not see these results.

    Qt Code:
    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <ElementDef verMajor="1" verMinor="0">
    3. <Elements>
    4. <Container name="L1Container" autoAdd="true">
    5. <Element name="L1Element1" title="L1Element1Title" label="L1Element1Label" drawn="false">
    6. <Properties>
    7. <Property name="Name" type="String" />
    8. </Properties>
    9. <Children>
    10. <Container name="L2Container" autoAdd="true">
    11. <Element name="L2Element1" title="L2Element1Title" label="L2Element1Label" drawn="false">
    12. <Slots>
    13. <Slot name="Slot1" abbreviation="Sl1" />
    14. <Slot name="Slot2" abbreviation="Sl2" />
    15. </Slots>
    16. <Signals>
    17. <Signal name="Signal1" abbreviation="Si1" event="CompleteEvent">
    18. <Argument value="FakeName" />
    19. </Signal>
    20. <Signal name="Signal2" abbreviation="Si2" event="CompleteEvent">
    21. <Argument value="FakeName" />
    22. </Signal>
    23. </Signals>
    24. </Element>
    25. <Element name="L2Element2" title="L2Element2Title" label="L2Element2Label" drawn="false">
    26. <Slots>
    27. <Slot name="Slot1" abbreviation="Sl1" />
    28. <Slot name="Slot2" abbreviation="Sl2" />
    29. </Slots>
    30. <Signals>
    31. <Signal name="Signal1" abbreviation="Si1" event="CompleteEvent">
    32. <Argument value="FakeName" />
    33. </Signal>
    34. <Signal name="Signal2" abbreviation="Si2" event="CompleteEvent">
    35. <Argument value="FakeName" />
    36. </Signal>
    37. </Signals>
    38. </Element>
    39. </Container>
    40. </Children>
    41. </Element>
    42. </Container>
    43. </Elements>
    44. </ElementDef>
    To copy to clipboard, switch view to plain text mode 

    Here is (basically) the code I've tried in an effort to get the children I want. You may notice the 'i' preceding my objects. Some use 'i' for integer and some use it for interface. It's what I use to denote a class instance so that I don't have to define (and remember) innumerable Hungarian-like abbreviations for the classes I use. Just a simple 'i' and an appropriate name.

    Qt Code:
    1. QDomNodeList iChildren;
    3. /* Here I expected to only get L1Element1, but got it and it's children named Element.*/
    4. iChildren = iChild.elementsByTagName("Element"); //iChild is a QDomElement straight from the DOM
    6. /*This just gave me everything below L1Container, which is less than useless.*/
    7. iChildren = iChild.childNodes();
    To copy to clipboard, switch view to plain text mode 

    If anyone has a clue what might be going on, I'd love to know. As it is, I need to get this thing moving so I'll have to use a different parsing API.

  2. #2
    Join Date
    Oct 2006
    New Delhi, India
    Thanked 334 Times in 317 Posts
    Qt products
    Unix/X11 Windows

    Default Re: Having trouble with direct child nodes using QtXml

    From the docs :
    QDomNodeList QDomElement::elementsByTagName ( const QString & tagname ) const
    Returns a QDomNodeList containing all descendent elements of this element that are called tagname. The order they are in the node list is the order they are encountered in a preorder traversal of the element tree.
    so the behaviour of elementsByTagName in ur code is justified.

    As for the childNodes(), Are you sure you were on the <Container name="L1Container" autoAdd="true"> tag when you used the childNodes() function ??

    Thirdly... what is iChild in your code ? How are you assigning value to it ??

  3. #3
    Join Date
    Jul 2008
    Qt products

    Default Re: Having trouble with direct child nodes using QtXml

    I see your point about elementsByTagName. Must've glossed over that when I read it earlier. iChild has a comment next to it describing what it is and where it's from, but in fact it was related to a bug I found in my code, so it no longer exists.

    The way I was processing the children of both a <Container> and an <Element> was to get their child nodes (actually in the case of the <Element>, it was the children of <Children>) with childNodes() and parse each in a for loop.

    What I've now done, thanks to an example from a work acquaintance, is grab the firstChildElement() and use something similar to:

    Qt Code:
    1. QDomElement iChild = iParent.firstChildElement();
    2. while (!iChild.isNull())
    3. {
    4. parseFunction(iChild);
    5. iChild = iChild.nextSiblingElement();
    6. }
    To copy to clipboard, switch view to plain text mode 

    Strangly enough, I had used this method before with TinyXML in a school project a while back but it didn't hit me until I saw it in an example. But, it is now working and I'm on to other things.

    Thanks for the reply!

Tags for this Thread


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.