QDomElement, index of node ?
-
For example if the XML has the following nodes:
<root> <name><c1 /></name> <name><c2/></name> <name><c3/></name> <name><c4/></name> </root>
The above is purely for the purposes of this post to illustrate what I want to do. Is there a way to get the index of any node in the DOM, in the above example, there are 4 nodes called name.
If I pick c3, I can get the parent node 'name' from the DOM. Can I get the index of the node, so in the above I would assume that the first node called name is 0, then 1, 2 and 3 ?
-
@SPlatten , fixed:
/** * @brief clsModXML::asArrays * @param robjElement : Reference to element to process * @param robjResult : Reference to JSON to populate * @param strParent : Optional, parent node name * @param intIndex : Optional, index of parent element */ void clsModXML::asArrays(QDomElement& robjElement, QJsonObject& robjResult ,QString strParent, int intIndex) { QDomNode::NodeType eNodeType = robjElement.nodeType(); if ( eNodeType != QDomNode::ElementNode ) { return; } QDomNamedNodeMap mpAttr = robjElement.attributes(); QJsonObject objAttr, objNode; for( int i=0; i<mpAttr.size(); i++ ) { QDomNode item(mpAttr.item(i)); eNodeType = item.nodeType(); if ( eNodeType != QDomNode::AttributeNode ) { continue; } objAttr.insert(item.nodeName(), item.nodeValue()); } objNode.insert(clsModXML::mscszAttrs, objAttr); if ( strParent.isEmpty() != true && intIndex >= 0 ) { QJsonObject objParent; objParent.insert(strParent, intIndex); objNode.insert(clsModXML::mscszParent, objParent); } QString strNodeName(robjElement.nodeName()); QJsonObject::const_iterator citNode = robjResult.find(strNodeName); QJsonArray aryNodes; if ( citNode != robjResult.end() ) { aryNodes = citNode->toArray(); } //Index of parent in the array intIndex = aryNodes.size(); //Add attributes node to array aryNodes.append(objNode); robjResult.insert(strNodeName, aryNodes); if ( robjElement.hasChildNodes() == true ) { //Process any child nodes int intChildren = robjElement.childNodes().size(); QDomNodeList lstChildNodes = robjElement.childNodes(); for( int c=0; c<intChildren; c++ ) { QDomElement objChildEl(lstChildNodes.item(c).toElement()); asArrays(objChildEl, robjResult, robjElement.nodeName(), intIndex); } } }
-
@SPlatten You can access the elements for example using https://doc.qt.io/qt-5/qdomdocument.html#elementsByTagName which returns a list and you can access the elements via an index https://doc.qt.io/qt-5/qdomnodelist.html#at. Or what is the question?
-
@jsulm , thank you, I've written a module which converts an XML document to JSON that was simple enough, now I want to produce a variant of this where by the JSON could contain arrays of all nodes from the XML where each node is an array of X, each element represents a single instance of the node and will have an attributes array and parent, where the parent details the node that is its parent and the index of the parent.
This is the function that I need help completing:
/** * @brief clsModXML::asArrays * @param robjElement : Reference to element to process * @param robjResult : Reference to JSON to populate * @param strParent : Optional, parent node name * @param intIndex : Optional, index of parent element */ void clsModXML::asArrays(QDomElement& robjElement, QJsonObject& robjResult ,QString strParent, int intIndex) { QDomNode::NodeType eNodeType = robjElement.nodeType(); if ( eNodeType != QDomNode::ElementNode ) { return; } QDomNamedNodeMap mpAttr = robjElement.attributes(); QJsonObject objAttr, objNode; for( int i=0; i<mpAttr.size(); i++ ) { QDomNode item(mpAttr.item(i)); eNodeType = item.nodeType(); if ( eNodeType != QDomNode::AttributeNode ) { continue; } objAttr.insert(item.nodeName(), item.nodeValue()); } objNode.insert(clsModXML::mscszAttrs, objAttr); QString strNodeName(robjElement.nodeName()); QJsonObject::const_iterator citNode = robjResult.find(strNodeName); QJsonArray aryNodes; if ( citNode != robjResult.end() ) { aryNodes = citNode->toArray(); } //Add attributes node to array aryNodes.append(objNode); robjResult.insert(strNodeName, aryNodes); if ( robjElement.hasChildNodes() == true ) { //Process any child nodes int intChildren = robjElement.childNodes().size(); QDomNodeList lstChildNodes = robjElement.childNodes(); for( int c=0; c<intChildren; c++ ) { QDomElement objChildEl(lstChildNodes.item(c).toElement()); asArrays(objChildEl, robjResult, robjElement.nodeName()); } } }
The last two parameters of asArrays are optional, the nested call of asArrays has the parent node name and this is where I need to put in the index of the parent element.
-
@SPlatten , fixed:
/** * @brief clsModXML::asArrays * @param robjElement : Reference to element to process * @param robjResult : Reference to JSON to populate * @param strParent : Optional, parent node name * @param intIndex : Optional, index of parent element */ void clsModXML::asArrays(QDomElement& robjElement, QJsonObject& robjResult ,QString strParent, int intIndex) { QDomNode::NodeType eNodeType = robjElement.nodeType(); if ( eNodeType != QDomNode::ElementNode ) { return; } QDomNamedNodeMap mpAttr = robjElement.attributes(); QJsonObject objAttr, objNode; for( int i=0; i<mpAttr.size(); i++ ) { QDomNode item(mpAttr.item(i)); eNodeType = item.nodeType(); if ( eNodeType != QDomNode::AttributeNode ) { continue; } objAttr.insert(item.nodeName(), item.nodeValue()); } objNode.insert(clsModXML::mscszAttrs, objAttr); if ( strParent.isEmpty() != true && intIndex >= 0 ) { QJsonObject objParent; objParent.insert(strParent, intIndex); objNode.insert(clsModXML::mscszParent, objParent); } QString strNodeName(robjElement.nodeName()); QJsonObject::const_iterator citNode = robjResult.find(strNodeName); QJsonArray aryNodes; if ( citNode != robjResult.end() ) { aryNodes = citNode->toArray(); } //Index of parent in the array intIndex = aryNodes.size(); //Add attributes node to array aryNodes.append(objNode); robjResult.insert(strNodeName, aryNodes); if ( robjElement.hasChildNodes() == true ) { //Process any child nodes int intChildren = robjElement.childNodes().size(); QDomNodeList lstChildNodes = robjElement.childNodes(); for( int c=0; c<intChildren; c++ ) { QDomElement objChildEl(lstChildNodes.item(c).toElement()); asArrays(objChildEl, robjResult, robjElement.nodeName(), intIndex); } } }