bool TestBaseLine::isDeepEqual(const QDomNode &n1, const QDomNode &n2) { if(n1.nodeType() != n2.nodeType()) return false; switch(n1.nodeType()) { case QDomNode::CommentNode: /* Fallthrough. */ case QDomNode::TextNode: { return static_cast<const QDomCharacterData &>(n1).data() == static_cast<const QDomCharacterData &>(n2).data(); } case QDomNode::ProcessingInstructionNode: { return n1.nodeName() == n2.nodeName() && n1.nodeValue() == n2.nodeValue(); } case QDomNode::DocumentNode: return isChildrenDeepEqual(n1.childNodes(), n2.childNodes()); case QDomNode::ElementNode: { return n1.localName() == n2.localName() && n1.namespaceURI() == n2.namespaceURI() && n1.nodeName() == n2.nodeName() && /* Yes, this one is needed in addition to localName(). */ isAttributesEqual(n1.attributes(), n2.attributes()) && isChildrenDeepEqual(n1.childNodes(), n2.childNodes()); } /* Fallthrough all these. */ case QDomNode::EntityReferenceNode: case QDomNode::CDATASectionNode: case QDomNode::EntityNode: case QDomNode::DocumentTypeNode: case QDomNode::DocumentFragmentNode: case QDomNode::NotationNode: case QDomNode::BaseNode: case QDomNode::CharacterDataNode: { Q_ASSERT_X(false, Q_FUNC_INFO, "An unsupported node type was encountered."); return false; } case QDomNode::AttributeNode: { Q_ASSERT_X(false, Q_FUNC_INFO, "This should never happen. QDom doesn't allow us to compare DOM attributes " "properly."); return false; } default: { Q_ASSERT_X(false, Q_FUNC_INFO, "Unhandled QDom::NodeType value."); return false; } } }
QString QDomNodeProto:: namespaceURI() const { QDomNode *item = qscriptvalue_cast<QDomNode*>(thisObject()); if (item) return item->namespaceURI(); return QString(); }
void cleanMathml(QDomElement pElement) { // Clean up the current element // Note: the idea is to remove all the attributes that are not in the // MathML namespace. Indeed, if we were to leave them in then the XSL // transformation would either do nothing or, worst, crash OpenCOR... static const QString MathmlNamespace = "http://www.w3.org/1998/Math/MathML"; QDomNamedNodeMap attributes = pElement.attributes(); QList<QDomNode> nonMathmlAttributes = QList<QDomNode>(); for (int i = 0, iMax = attributes.count(); i < iMax; ++i) { QDomNode attribute = attributes.item(i); if (attribute.namespaceURI().compare(MathmlNamespace)) nonMathmlAttributes << attribute; } foreach (QDomNode nonMathmlAttribute, nonMathmlAttributes) pElement.removeAttributeNode(nonMathmlAttribute.toAttr()); // Go through the element's child elements, if any, and clean them up for (QDomElement childElement = pElement.firstChildElement(); !childElement.isNull(); childElement = childElement.nextSiblingElement()) { cleanMathml(childElement); } }
// stripExtraNS // // This function removes namespace information from various nodes for // display purposes only (the element is pretty much useless for processing // after this). We do this because QXml is a bit overzealous about outputting // redundant namespaces. static QDomElement stripExtraNS(const QDomElement &e) { // find closest parent with a namespace QDomNode par = e.parentNode(); while(!par.isNull() && par.namespaceURI().isNull()) par = par.parentNode(); bool noShowNS = false; if(!par.isNull() && par.namespaceURI() == e.namespaceURI()) noShowNS = true; // build qName (prefix:localName) QString qName; if(!e.prefix().isEmpty()) qName = e.prefix() + ':' + e.localName(); else qName = e.tagName(); QDomElement i; int x; if(noShowNS) i = e.ownerDocument().createElement(qName); else i = e.ownerDocument().createElementNS(e.namespaceURI(), qName); // copy attributes QDomNamedNodeMap al = e.attributes(); for(x = 0; x < al.count(); ++x) { QDomAttr a = al.item(x).cloneNode().toAttr(); // don't show xml namespace if(a.namespaceURI() == NS_XML) i.setAttribute(QString("xml:") + a.name(), a.value()); else i.setAttributeNodeNS(a); } // copy children QDomNodeList nl = e.childNodes(); for(x = 0; x < nl.count(); ++x) { QDomNode n = nl.item(x); if(n.isElement()) i.appendChild(stripExtraNS(n.toElement())); else i.appendChild(n.cloneNode()); } return i; }
bool TestBaseLine::isAttributesEqual(const QDomNamedNodeMap &cl1, const QDomNamedNodeMap &cl2) { const unsigned int len = cl1.length(); pDebug() << "LEN:" << len; if(len == cl2.length()) { for(unsigned int i1 = 0; i1 < len; ++i1) { const QDomNode attr1(cl1.item(i1)); Q_ASSERT(!attr1.isNull()); /* This is set if attr1 cannot be found at all in cl2. */ bool earlyExit = false; for(unsigned int i2 = 0; i2 < len; ++i2) { const QDomNode attr2(cl2.item(i2)); Q_ASSERT(!attr2.isNull()); pDebug() << "ATTR1:" << attr1.localName() << attr1.namespaceURI() << attr1.prefix() << attr1.nodeName(); pDebug() << "ATTR2:" << attr2.localName() << attr2.namespaceURI() << attr2.prefix() << attr2.nodeName(); if(attr1.localName() == attr2.localName() && attr1.namespaceURI() == attr2.namespaceURI() && attr1.prefix() == attr2.prefix() && attr1.nodeName() == attr2.nodeName() && /* Yes, needed in addition to all the other. */ attr1.nodeValue() == attr2.nodeValue()) { earlyExit = true; break; } } if(!earlyExit) { /* An attribute was found that doesn't exist in the other list so exit. */ return false; } } return true; } else return false; }
static QDomElement oldStyleNS(const QDomElement &e) { // find closest parent with a namespace QDomNode par = e.parentNode(); while(!par.isNull() && par.namespaceURI().isNull()) par = par.parentNode(); bool noShowNS = false; if(!par.isNull() && par.namespaceURI() == e.namespaceURI()) noShowNS = true; QDomElement i; uint x; //if(noShowNS) i = e.ownerDocument().createElement(e.tagName()); //else // i = e.ownerDocument().createElementNS(e.namespaceURI(), e.tagName()); // copy attributes QDomNamedNodeMap al = e.attributes(); for(x = 0; x < al.count(); ++x) i.setAttributeNode(al.item(x).cloneNode().toAttr()); if(!noShowNS) i.setAttribute("xmlns", e.namespaceURI()); // copy children QDomNodeList nl = e.childNodes(); for(x = 0; x < nl.count(); ++x) { QDomNode n = nl.item(x); if(n.isElement()) i.appendChild(oldStyleNS(n.toElement())); else i.appendChild(n.cloneNode()); } return i; }
void BasicProtocol::extractStreamError(const QDomElement &e) { QString text; QDomElement appSpec; QDomElement t = firstChildElement(e); if(t.isNull() || t.namespaceURI() != NS_STREAMS) { // probably old-style error errCond = -1; errText = e.text(); } else errCond = stringToStreamCond(t.tagName()); if(errCond != -1) { if(errCond == SeeOtherHost) otherHost = t.text(); t = e.elementsByTagNameNS(NS_STREAMS, "text").item(0).toElement(); if(!t.isNull()) text = t.text(); // find first non-standard namespaced element QDomNodeList nl = e.childNodes(); for(int n = 0; n < nl.count(); ++n) { QDomNode i = nl.item(n); if(i.isElement() && i.namespaceURI() != NS_STREAMS) { appSpec = i.toElement(); break; } } errText = text; errAppSpec = appSpec; } }
/** \brief Reads the error from XML This function finds and reads the error element \a e. You need to provide the base namespace of the stream which this stanza belongs to (probably by using stream.baseNS() function). */ bool Stanza::Error::fromXml(const QDomElement &e, const QString &baseNS) { if(e.tagName() != "error" && e.namespaceURI() != baseNS) return false; // type type = Private::stringToErrorType(e.attribute("type")); // condition QDomNodeList nl = e.childNodes(); QDomElement t; condition = -1; int n; for(n = 0; n < nl.count(); ++n) { QDomNode i = nl.item(n); t = i.toElement(); if(!t.isNull()) { // FIX-ME: this shouldn't be needed if(t.namespaceURI() == NS_STANZAS || t.attribute("xmlns") == NS_STANZAS) { condition = Private::stringToErrorCond(t.tagName()); if (condition != -1) break; } } } // code originalCode = e.attribute("code").toInt(); // try to guess type/condition if(type == -1 || condition == -1) { QPair<int, int> guess(-1, -1); if (originalCode) guess = Private::errorCodeToTypeCond(originalCode); if (type == -1) type = guess.first != -1 ? guess.first : Cancel; if (condition == -1) condition = guess.second != -1 ? guess.second : UndefinedCondition; } // text t = e.elementsByTagNameNS(NS_STANZAS, "text").item(0).toElement(); if(!t.isNull()) text = t.text().trimmed(); else text = e.text().trimmed(); // appspec: find first non-standard namespaced element appSpec = QDomElement(); nl = e.childNodes(); for(n = 0; n < nl.count(); ++n) { QDomNode i = nl.item(n); if(i.isElement() && i.namespaceURI() != NS_STANZAS) { appSpec = i.toElement(); break; } } return true; }