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); } }
void DomConvenience::clearAttributes(QDomElement& e) { QDomNamedNodeMap attrMap = e.attributes(); QDomNode attrNode; for (uint i = attrMap.length(); i > 0; --i) e.removeAttributeNode(attrMap.item(i - 1).toAttr()); }
static PyObject *meth_QDomElement_removeAttributeNode(PyObject *sipSelf, PyObject *sipArgs) { PyObject *sipParseErr = NULL; { const QDomAttr* a0; QDomElement *sipCpp; if (sipParseArgs(&sipParseErr, sipArgs, "BJ9", &sipSelf, sipType_QDomElement, &sipCpp, sipType_QDomAttr, &a0)) { QDomAttr*sipRes; sipRes = new QDomAttr(sipCpp->removeAttributeNode(*a0)); return sipConvertFromNewType(sipRes,sipType_QDomAttr,NULL); } } /* Raise an exception if the arguments couldn't be parsed. */ sipNoMethod(sipParseErr, sipName_QDomElement, sipName_removeAttributeNode, doc_QDomElement_removeAttributeNode); return NULL; }
void cleanDomElement(QDomElement &pDomElement, QMap<QString, QString> &pElementsAttributes) { // Serialise all the element's attributes and sort their serialised version // before removing them from the element and adding a new attribute that // will later on be used for string replacement static qulonglong attributeNumber = 0; static const int ULLONG_WIDTH = ceil(log(ULLONG_MAX)); if (pDomElement.hasAttributes()) { QStringList serialisedAttributes = QStringList(); QDomNamedNodeMap domElementAttributes = pDomElement.attributes(); QDomAttr attributeNode; while (domElementAttributes.count()) { // Serialise (ourselves) the element's attribute // Note: to rely on QDomNode::save() to do the serialisation isn't // good enough. Indeed, if it is going to be fine for an // attribute that doesn't have a prefix, e.g. // name="my_name" // it may not be fine for an attribute with a prefix, e.g. // cmeta:id="my_cmeta_id" // since depending on how that attribute has been created // (i.e. using QDomDocument::createAttribute() or // QDomDocument::createAttributeNS()), then it may or not have // a namespace associated with it. If it does, then its // serialisation will look something like // cmeta:id="my_cmeta_id" xmlns:cmeta="http://www.cellml.org/metadata/1.0#" // which is clearly not what we want since that's effectively // two attributes in one. So, we need to separate them, which // is what we do here, after making sure that the namespace // for the attribute is not already defined for the given DOM // element... attributeNode = domElementAttributes.item(0).toAttr(); if (attributeNode.namespaceURI().isEmpty()) { serialisedAttributes << attributeNode.name()+"=\""+attributeNode.value()+"\""; } else { serialisedAttributes << attributeNode.prefix()+":"+attributeNode.name()+"=\""+attributeNode.value()+"\""; if ( attributeNode.prefix().compare(pDomElement.prefix()) && attributeNode.namespaceURI().compare(pDomElement.namespaceURI())) { serialisedAttributes << "xmlns:"+attributeNode.prefix()+"=\""+attributeNode.namespaceURI()+"\""; } } // Remove the attribute node from the element pDomElement.removeAttributeNode(attributeNode); } // Sort the serialised attributes, using the attributes' name, and // remove duplicates, if any std::sort(serialisedAttributes.begin(), serialisedAttributes.end(), sortSerialisedAttributes); serialisedAttributes.removeDuplicates(); // Keep track of the serialisation of the element's attribute QString elementAttributes = QString("Element%1Attributes").arg(++attributeNumber, ULLONG_WIDTH, 10, QChar('0')); pElementsAttributes.insert(elementAttributes, serialisedAttributes.join(" ")); // Add a new attribute to the element // Note: this attribute, once serialised by QDomDocument::save(), will // be used to do a string replacement (see // qDomDocumentToString())... domElementAttributes.setNamedItem(pDomElement.ownerDocument().createAttribute(elementAttributes)); } // Recursively clean ourselves for (QDomElement childElement = pDomElement.firstChildElement(); !childElement.isNull(); childElement = childElement.nextSiblingElement()) { cleanDomElement(childElement, pElementsAttributes); } }