Re: [xml] XHTML Doc serialization and meta element



Daniel Veillard wrote:


 Okay I read the patch, this is basically the way I would prefer to see
this implemented. Of course there might be some details to get right,
I would expect for example the serialization to be the same to the old
code in the majority of the cases (i.e. running the test suite would raise
a difference only for the XHTML document with an http-equiv meta element
in head assuming we have any of those). Goal is to have the least surprize
possible for those already using the feature whithout knowing :-), and
avoid the modification of the tree which is nasty.

 So I like it but the devil is in the details :-)
Here is what I have come up with for this. HTMLTree serialization not included here - had started it but it breaks about half of the HTML tests so not so sure if this would be a good thing. If the HTMLTree serialization is to be left alone, I would suggest removal of the htmlSetMetaEncoding calls from the htmlSaveFileFormat function as this is the only function to implement it making it inconsistant with the rest of the HTMLTree serialization functions.

On to the patch. It doesn't break any of the tests (there was an XHTML document with the meta tag but it was already using the defaulting values), but it does alter the old behavior a bit. - calling xmlNodeDumpOutput with a head element will produce the meta element if not present, its parent is an html element and doc is XHTML. - meta element only added if a meta element with the http-equiv attr having value Content-Type does not exist Old functionality always added and would remove a meta element with http-equiv attribute having value Content-Type and a content attribute An existing meta element is no longer required to have the content attribute

That was really all I could see for behavior changes.

Rob
Index: xmlsave.c
===================================================================
RCS file: /cvs/gnome/gnome-xml/xmlsave.c,v
retrieving revision 1.25
diff -c -r1.25 xmlsave.c
*** xmlsave.c   8 Aug 2005 14:44:11 -0000       1.25
--- xmlsave.c   26 Aug 2005 01:32:44 -0000
***************
*** 860,871 ****
        is_xhtml = xmlIsXHTML(dtd->SystemID, dtd->ExternalID);
        if (is_xhtml < 0) is_xhtml = 0;
      }
-     if (is_xhtml) {
-       if (encoding != NULL)
-           htmlSetMetaEncoding(cur, (const xmlChar *) ctxt->encoding);
-       else
-           htmlSetMetaEncoding(cur, BAD_CAST "UTF-8");
-     }
  #endif
      if (cur->children != NULL) {
          xmlNodePtr child = cur->children;
--- 860,865 ----
***************
*** 1086,1092 ****
   */
  static void
  xhtmlNodeDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
!     int format;
      xmlNodePtr tmp;
      xmlChar *start, *end;
      xmlOutputBufferPtr buf;
--- 1080,1086 ----
   */
  static void
  xhtmlNodeDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
!     int format, addmeta = 0;
      xmlNodePtr tmp;
      xmlChar *start, *end;
      xmlOutputBufferPtr buf;
***************
*** 1210,1227 ****
      if (cur->properties != NULL)
          xhtmlAttrListDumpOutput(ctxt, cur->properties);
  
      if ((cur->type == XML_ELEMENT_NODE) && (cur->children == NULL)) {
        if (((cur->ns == NULL) || (cur->ns->prefix == NULL)) &&
!           (xhtmlIsEmpty(cur) == 1)) {
            /*
             * C.2. Empty Elements
             */
            xmlOutputBufferWrite(buf, 3, " />");
        } else {
            /*
             * C.3. Element Minimization and Empty Element Content
             */
!           xmlOutputBufferWrite(buf, 3, "></");
            if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
                xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
                xmlOutputBufferWrite(buf, 1, ":");
--- 1204,1256 ----
      if (cur->properties != NULL)
          xhtmlAttrListDumpOutput(ctxt, cur->properties);
  
+       if ((cur->type == XML_ELEMENT_NODE) && 
+               (cur->parent != NULL) && 
+               (cur->parent->parent == (xmlNodePtr) cur->doc) && 
+               xmlStrEqual(cur->name, BAD_CAST"head") && 
+               xmlStrEqual(cur->parent->name, BAD_CAST"html")) {
+ 
+               tmp = cur->children;
+               while (tmp != NULL) {
+                       if (xmlStrEqual(tmp->name, BAD_CAST"meta")) {
+                               xmlChar *httpequiv;
+ 
+                               httpequiv = xmlGetProp(tmp, BAD_CAST"http-equiv");
+                               if (xmlStrcasecmp(httpequiv, BAD_CAST"Content-Type") == 0) {
+                                       xmlFree(httpequiv);
+                                       break;
+                               }
+                               xmlFree(httpequiv);
+                       }
+                       tmp = tmp->next;
+               }
+               if (tmp == NULL)
+                       addmeta = 1;
+       }
+ 
      if ((cur->type == XML_ELEMENT_NODE) && (cur->children == NULL)) {
        if (((cur->ns == NULL) || (cur->ns->prefix == NULL)) &&
!           ((xhtmlIsEmpty(cur) == 1) && (addmeta == 0))) {
            /*
             * C.2. Empty Elements
             */
            xmlOutputBufferWrite(buf, 3, " />");
        } else {
+               if (addmeta == 1) {
+                       xmlOutputBufferWrite(buf, 1, ">");
+                       xmlOutputBufferWriteString(buf,
+                               "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=");
+                       if (ctxt->encoding) {
+                               xmlOutputBufferWriteString(buf, (const char *)ctxt->encoding);
+                       } else {
+                               xmlOutputBufferWrite(buf, 5, "UTF-8");
+                       }
+                       xmlOutputBufferWrite(buf, 3, "\" /");
+               }
            /*
             * C.3. Element Minimization and Empty Element Content
             */
!           xmlOutputBufferWrite(buf, 3, "></");
            if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
                xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
                xmlOutputBufferWrite(buf, 1, ":");
***************
*** 1232,1237 ****
--- 1261,1276 ----
        return;
      }
      xmlOutputBufferWrite(buf, 1, ">");
+       if (addmeta == 1) {
+               xmlOutputBufferWriteString(buf,
+                       "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=");
+               if (ctxt->encoding) {
+                       xmlOutputBufferWriteString(buf, (const char *)ctxt->encoding);
+               } else {
+                       xmlOutputBufferWrite(buf, 5, "UTF-8");
+               }
+               xmlOutputBufferWrite(buf, 4, "\" />");
+       }
      if ((cur->type != XML_ELEMENT_NODE) && (cur->content != NULL)) {
        xmlOutputBufferWriteEscape(buf, cur->content, ctxt->escape);
      }
***************
*** 1832,1846 ****
          is_xhtml = xmlIsXHTML(dtd->SystemID, dtd->ExternalID);
          if (is_xhtml < 0)
              is_xhtml = 0;
-         if ((is_xhtml) && (cur->parent == (xmlNodePtr) doc) &&
-             (cur->type == XML_ELEMENT_NODE) &&
-             (xmlStrEqual(cur->name, BAD_CAST "html"))) {
-             if (encoding != NULL)
-                 htmlSetMetaEncoding((htmlDocPtr) doc,
-                                     (const xmlChar *) encoding);
-             else
-                 htmlSetMetaEncoding((htmlDocPtr) doc, BAD_CAST "UTF-8");
-         }
      }
  
      if (is_xhtml)
--- 1871,1876 ----


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]