Beispiel #1
0
static void findUsedNamespaces(DFDocument *doc, DFNode *node, char *used, NamespaceID count)
{
    if (node->tag < MIN_ELEMENT_TAG)
        return;;
    const TagDecl *tagDecl = DFNameMapNameForTag(doc->map,node->tag);
    assert(tagDecl != NULL);
    assert(tagDecl->namespaceID < count);
    used[tagDecl->namespaceID] = 1;

    // Attributes
    if (node->tag >= MIN_ELEMENT_TAG) {
        for (unsigned int i = 0; i < node->attrsCount; i++) {
            Tag tag = node->attrs[i].tag;
            const TagDecl *attrDecl = DFNameMapNameForTag(doc->map,tag);
            assert(attrDecl != NULL);
            if ((attrDecl->namespaceID != NAMESPACE_NULL) &&
                (attrDecl->namespaceID != NAMESPACE_XML))
                used[attrDecl->namespaceID] = 1;
        }
    }

    // Children
    for (DFNode *child = node->first; child != NULL; child = child->next)
        findUsedNamespaces(doc,child,used,count);
}
Beispiel #2
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);
}
Beispiel #3
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);
}
Beispiel #4
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);
}
Beispiel #5
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;
}
Beispiel #6
0
const char *DFTagName(DFDocument *doc, Tag tag)
{
    const TagDecl *tagDecl = DFNameMapNameForTag(doc->map,tag);
    return (tagDecl != NULL) ? tagDecl->localName : NULL;
}
Beispiel #7
0
static void SAXStartElementNS(void *ctx, const xmlChar *localname,
                              const xmlChar *prefix, const xmlChar *URI,
                              int nb_namespaces, const xmlChar **namespaces,
                              int nb_attributes, int nb_defaulted, const xmlChar **attributes)
{
    DFSAXParser *parser = (DFSAXParser *)ctx;

    if (parser->ignoreDepth > 0) {
        parser->ignoreDepth++;
        return;
    }

    for (int i = 0; i < nb_namespaces; i++) {
        const xmlChar *nsPrefix = namespaces[i*2];
        const xmlChar *nsURI = namespaces[i*2+1];
        DFNameMapFoundNamespace(parser->document->map,(const char *)nsURI,(const char *)nsPrefix);
    }

    Tag tag = DFNameMapTagForName(parser->document->map,(const char *)URI,(const char *)localname);

    if (parser->compatibility != NULL) {
        const TagDecl *tagDecl = DFNameMapNameForTag(parser->document->map,tag);
        MCAction action = DFMarkupCompatibilityLookup(parser->compatibility,tagDecl->namespaceID,tag,1);
        if (action == MCActionIgnore) {
            parser->ignoreDepth++;
            return;
        }
    }

    if (parser->compatibility != NULL) {
        DFMarkupCompatibilityPush(parser->compatibility,nb_namespaces,(const char **)namespaces,parser->document->map);
    }

    DFNode *element = DFCreateElement(parser->document,tag);
    for (int i = 0; i < nb_attributes; i++) {
        const xmlChar *attrLocalName = attributes[i*5+0];
        const xmlChar *attrURI = attributes[i*5+2];
        const xmlChar *attrValueStart = attributes[i*5+3];
        const xmlChar *attrValueEnd = attributes[i*5+4];
        unsigned long attrValueLen = (unsigned long)(attrValueEnd - attrValueStart);

        Tag attrTag = DFNameMapTagForName(parser->document->map,(const char *)attrURI,(const char *)attrLocalName);
        const TagDecl *attrTagDecl = DFNameMapNameForTag(parser->document->map,attrTag);
        char *attrValue = (char *)xmalloc(attrValueLen+1);
        memcpy(attrValue,attrValueStart,attrValueLen);
        attrValue[attrValueLen] = '\0';
        if (parser->compatibility != NULL) {
            switch (attrTag) {
                case MC_IGNORABLE:
                case MC_PROCESSCONTENT:
                case MC_MUSTUNDERSTAND:
                    DFMarkupCompatibilityProcessAttr(parser->compatibility,attrTag,attrValue,parser->document->map);
                    break;
                default: {
                    MCAction action = DFMarkupCompatibilityLookup(parser->compatibility,attrTagDecl->namespaceID,0,0);
                    if (action != MCActionIgnore)
                        DFSetAttribute(element,attrTag,attrValue);
                    break;
                }
            }
        }
        else {
            DFSetAttribute(element,attrTag,attrValue);
        }
        free(attrValue);
    }

    DFAppendChild(parser->parent,element);
    parser->parent = element;
    if (parser->document->root == NULL)
        parser->document->root = element;
}
Beispiel #8
0
const TagDecl *DFBuiltinMapNameForTag(Tag tag)
{
    return DFNameMapNameForTag(BuiltinMapGet(),tag);
}