Example #1
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)

    // Go through the element's child elements, if any, and clean them up

    for (QDomElement childElement = pElement.firstChildElement();
         !childElement.isNull(); childElement = childElement.nextSiblingElement()) {
Example #2
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))

            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;
Example #4
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


        // Sort the serialised attributes, using the attributes' name, and
        // remove duplicates, if any

        std::sort(serialisedAttributes.begin(), serialisedAttributes.end(), sortSerialisedAttributes);


        // 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())...


    // Recursively clean ourselves

    for (QDomElement childElement = pDomElement.firstChildElement();
         !childElement.isNull(); childElement = childElement.nextSiblingElement()) {
        cleanDomElement(childElement, pElementsAttributes);