Ejemplo n.º 1
0
static void writeAttributes(Serialization *serialization, DFNode *element)
{
    // Sort the keys by their tag, to ensure that we always write attributes out in the same order.
    // This is important for automated tests which rely on consistent output for a given XML tree.
    DFAttribute *attrs = (DFAttribute *)xmalloc(element->attrsCount*sizeof(DFAttribute));
    memcpy(attrs,element->attrs,element->attrsCount*sizeof(DFAttribute));
    qsort(attrs,element->attrsCount,sizeof(DFAttribute),compareAttrs);

    for (unsigned int i = 0; i < element->attrsCount; i++) {
        Tag tag = attrs[i].tag;

        const TagDecl *tagDecl = DFNameMapNameForTag(serialization->doc->map,tag);
        assert(tagDecl != NULL);
        const NamespaceDecl *nsDecl = DFNameMapNamespaceForID(serialization->doc->map,tagDecl->namespaceID);
        assert(nsDecl != NULL);

        const xmlChar *prefix = (const xmlChar *)nsDecl->prefix;
        const xmlChar *localName = (const xmlChar *)tagDecl->localName;
        const xmlChar *value = (const xmlChar *)attrs[i].value;

        if (serialization->html && (tagDecl->namespaceID == NAMESPACE_HTML))
            xmlTextWriterWriteAttribute(serialization->writer,localName,value);
        else
            xmlTextWriterWriteAttributeNS(serialization->writer,prefix,localName,NULL,value);
    }
    free(attrs);
}
Ejemplo n.º 2
0
static void writeElement(Serialization *serialization, DFNode *element, int depth)
{
    const TagDecl *tagDecl = DFNameMapNameForTag(serialization->doc->map,element->tag);
    assert(tagDecl != NULL);
    const NamespaceDecl *nsDecl = DFNameMapNamespaceForID(serialization->doc->map,tagDecl->namespaceID);
    assert(nsDecl != NULL);

    const xmlChar *prefix = (const xmlChar *)nsDecl->prefix;
    const xmlChar *localName = (const xmlChar *)tagDecl->localName;

    if (serialization->indent && (element->parent != element->doc->docNode))
        xmlTextWriterWriteRawLen(serialization->writer,INDENT,1+depth);

    if (serialization->html || (tagDecl->namespaceID == serialization->defaultNS))
        xmlTextWriterStartElement(serialization->writer,localName);
    else
        xmlTextWriterStartElementNS(serialization->writer,prefix,localName,NULL);

    if ((element->parent == serialization->doc->docNode) && !serialization->html)
        writeNamespaceDeclarations(serialization,element);

    writeAttributes(serialization,element);

    // Check if all children are text nodes. If this is true; we should treat them as if they are a single text
    // node, and not do any indentation.
    int allChildrenText = 1;
    for (DFNode *child = element->first; child != NULL; child = child->next) {
        if (child->tag != DOM_TEXT)
            allChildrenText = 0;
    }

    if (allChildrenText) {
        int oldIndent = serialization->indent;
        serialization->indent = 0;
        for (DFNode *child = element->first; child != NULL; child = child->next)
            writeNode(serialization,child,depth+2);
        serialization->indent = oldIndent;
    }
    else {
        for (DFNode *child = element->first; child != NULL; child = child->next)
            writeNode(serialization,child,depth+2);
    }

    if (serialization->indent && (element->first != NULL) && !allChildrenText) {
        if ((element->first != element->last) ||
            (element->first->tag != DOM_TEXT))
        xmlTextWriterWriteRawLen(serialization->writer,INDENT,1+depth);
    }

    if (serialization->html && (element->first == NULL) && HTML_requiresCloseTag(element->tag)) {
        xmlTextWriterWriteString(serialization->writer,(xmlChar *)"");
    }

    xmlTextWriterEndElement(serialization->writer);
}
// FIXME: Not covered by tests
void DFMarkupCompatibilityProcessAttr(DFMarkupCompatibility *mc, Tag attr, const char *value, DFNameMap *map)
{
    const char **tokens = DFStringTokenize(value,isspace);
    for (int tokIndex = 0; tokens[tokIndex]; tokIndex++) {
        const char *component = tokens[tokIndex];

        char *prefix = NULL;
        char *localName = NULL;
        const char *colon = strchr(component,':');
        if (colon != NULL) {
            size_t colonPos = colon - component;
            prefix = DFSubstring(component,0,colonPos);
            localName = DFSubstring(component,colonPos+1,strlen(component));
        }
        else {
            prefix = xstrdup(component);
            localName = NULL;
        }

        const char *nsIdStr = NULL;

        // Find namespace ID for prefix
        for (int recordIndex = mc->depth-1; recordIndex >= 0; recordIndex--) {
            MCRecord *record = &mc->records[recordIndex];
            if (record->namespaces != NULL)
                nsIdStr = DFHashTableLookup(record->namespaces,prefix);
        }

        if (nsIdStr != NULL) {

            NamespaceID nsId = atoi(nsIdStr);
            Tag tag = 0;

            const NamespaceDecl *nsDecl = DFNameMapNamespaceForID(map,nsId);

            if (localName != NULL)
                tag = DFNameMapTagForName(map,nsDecl->namespaceURI,localName);

            switch (attr) {
                case MC_IGNORABLE:
                    addDeclToRecord(&mc->records[mc->depth-1],nsId,tag,MCActionIgnore);
                    break;
                case MC_PROCESSCONTENT:
                    addDeclToRecord(&mc->records[mc->depth-1],nsId,tag,MCActionProcessContent);
                    break;
                case MC_MUSTUNDERSTAND:
                    addDeclToRecord(&mc->records[mc->depth-1],nsId,tag,MCActionMustUnderstand);
                    break;
            }
        }
        free(prefix);
        free(localName);
    }
    free(tokens);
}
Ejemplo n.º 4
0
DFNode *fromTidyNode(DFDocument *htmlDoc, TidyDoc tdoc, TidyNode tnode)
{
    switch (tidyNodeGetType(tnode)) {
        case TidyNode_Text: {
            char *value = copyTidyNodeValue(tnode,tdoc);
            DFNode *result = DFCreateTextNode(htmlDoc,value);
            free(value);
            return result;
        }
        case TidyNode_CDATA:
            break;
        case TidyNode_Comment:
            break;
        case TidyNode_Root:
            printf("Have root\n");
            break;
        default: {
            const char *name = tidyNodeGetName(tnode);
            if (name == NULL) {
                printf("NULL name for %p, type %d\n",tnode,tidyNodeGetType(tnode));
                return NULL;
            }
            const NamespaceDecl *namespaceDecl = DFNameMapNamespaceForID(htmlDoc->map,NAMESPACE_HTML);
            Tag tag = DFNameMapTagForName(htmlDoc->map,namespaceDecl->namespaceURI,name);
            DFNode *element = DFCreateElement(htmlDoc,tag);

            for (TidyAttr tattr = tidyAttrFirst(tnode); tattr != NULL; tattr = tidyAttrNext(tattr)) {
                const char *name = tidyAttrName(tattr);
                const char *value = tidyAttrValue(tattr);
                if (value == NULL) // Can happen in case of the empty string
                    value = "";;
                Tag attrTag = DFNameMapTagForName(htmlDoc->map,namespaceDecl->namespaceURI,name);
                DFSetAttribute(element,attrTag,value);
            }

            for (TidyNode tchild = tidyGetChild(tnode); tchild != NULL; tchild = tidyGetNext(tchild)) {
                DFNode *child = fromTidyNode(htmlDoc,tdoc,tchild);
                if (child != NULL)
                    DFAppendChild(element,child);
            }
            return element;
        }
    }
    return NULL;
}
Ejemplo n.º 5
0
static void writeNamespaceDeclarations(Serialization *serialization, DFNode *node)
{
    NamespaceID count = DFNameMapNamespaceCount(serialization->doc->map);
    char *used = (char *)xcalloc(1,count);
    findUsedNamespaces(serialization->doc,node,used,count);
    for (NamespaceID nsId = 1; nsId < count; nsId++) { // don't write null namespace
        if (used[nsId]) {
            const NamespaceDecl *nsDecl = DFNameMapNamespaceForID(serialization->doc->map,nsId);
            const xmlChar *prefix = (const xmlChar *)nsDecl->prefix;
            const xmlChar *URI = (const xmlChar *)nsDecl->namespaceURI;
            if (nsId == serialization->defaultNS)
                xmlTextWriterWriteAttribute(serialization->writer,(const xmlChar *)"xmlns",URI);
            else
                xmlTextWriterWriteAttributeNS(serialization->writer,(const xmlChar *)"xmlns",prefix,NULL,URI);
        }
    }
    free(used);
}
Ejemplo n.º 6
0
static void SAXStartElement(void *ctx, const xmlChar *fullname, const xmlChar **atts)
{
    DFSAXParser *parser = (DFSAXParser *)ctx;
    const NamespaceDecl *namespaceDecl = DFNameMapNamespaceForID(parser->document->map,NAMESPACE_HTML);
    Tag tag = DFNameMapTagForName(parser->document->map,namespaceDecl->namespaceURI,(const char *)fullname);
    DFNode *element = DFCreateElement(parser->document,tag);
    if (atts != NULL) {
        for (int i = 0; atts[i] != NULL; i += 2) {
            const xmlChar *name = atts[i];
            const xmlChar *value = atts[i+1];
            Tag attrTag = DFNameMapTagForName(parser->document->map,namespaceDecl->namespaceURI,(const char *)name);
            DFSetAttribute(element,attrTag,(const char *)value);
        }
    }
    DFAppendChild(parser->parent,element);
    parser->parent = element;
    if (parser->document->root == NULL)
        parser->document->root = element;
}
Ejemplo n.º 7
0
static void writeElement(Serialization *serialization, DFNode *element, int depth)
{
    const TagDecl *tagDecl = DFNameMapNameForTag(serialization->doc->map,element->tag);
    assert(tagDecl != NULL);
    const NamespaceDecl *nsDecl = DFNameMapNamespaceForID(serialization->doc->map,tagDecl->namespaceID);
    assert(nsDecl != NULL);

    const xmlChar *prefix = (const xmlChar *)nsDecl->prefix;
    const xmlChar *localName = (const xmlChar *)tagDecl->localName;

    if (serialization->indent && (element->parent != element->doc->docNode))
        xmlTextWriterWriteRawLen(serialization->writer,INDENT,1+depth);

    if (serialization->html || (tagDecl->namespaceID == serialization->defaultNS))
        xmlTextWriterStartElement(serialization->writer,localName);
    else
        xmlTextWriterStartElementNS(serialization->writer,prefix,localName,NULL);

    if ((element->parent == serialization->doc->docNode) && !serialization->html)
        writeNamespaceDeclarations(serialization,element);

    writeAttributes(serialization,element);

    for (DFNode *child = element->first; child != NULL; child = child->next)
        writeNode(serialization,child,depth+2);

    if (serialization->indent && (element->first != NULL)) {
        if ((element->first != element->last) ||
            (element->first->tag != DOM_TEXT))
        xmlTextWriterWriteRawLen(serialization->writer,INDENT,1+depth);
    }

    if (serialization->html && (element->first == NULL) && HTML_requiresCloseTag(element->tag)) {
        xmlTextWriterWriteString(serialization->writer,(xmlChar *)"");
    }

    xmlTextWriterEndElement(serialization->writer);
}
Ejemplo n.º 8
0
const char *DFTagURI(DFDocument *doc, Tag tag)
{
    const TagDecl *tagDecl = DFNameMapNameForTag(doc->map,tag);
    const NamespaceDecl *nsDecl = (tagDecl == NULL) ? NULL : DFNameMapNamespaceForID(doc->map,tagDecl->namespaceID);
    return (nsDecl != NULL) ? nsDecl->namespaceURI : NULL;
}