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); }
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); }
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); }
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); }
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; }
const char *DFTagName(DFDocument *doc, Tag tag) { const TagDecl *tagDecl = DFNameMapNameForTag(doc->map,tag); return (tagDecl != NULL) ? tagDecl->localName : NULL; }
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; }
const TagDecl *DFBuiltinMapNameForTag(Tag tag) { return DFNameMapNameForTag(BuiltinMapGet(),tag); }