Re: [xslt] Problem with DOCTYPE



On Tue, May 08, 2001 at 09:15:10PM +0800, William M. Brack wrote:
> In libxslt-0.9.0 we are getting duplicate DOCTYPE declarations in our output
> when we use
>     <xsl:output method="xml" encoding="UTF-8"
>     doctype-public="-//WAPFORUM//DTD WML 1.1//EN"
>     doctype-system="http://www.wapforum.org/DTD/wml_1.1.xml"/>
> 

  Ouch, right :-)

> This seems to be related to the (perfectly proper) enhancement to the "if"
> statement (line 2547) near the end of transform.c.  Apparently,  when
> xmlCreateIntSubset is called it creates a DOCTYPE node. Then, when
> xsltSaveResultTo is called to output the result, it produces a DOCTYPE.
> However, when xmlNodeDumpOutput is subsequently called, the
> previously-created DOCTYPE node is also output.
> 
> I guess that the coding within xsltSaveResultTo which produces the DOCTYPE
> should be removed, but would appreciate your taking a look at it.

  Perfectly right, the generation of the doctype information when the
document is produced is important, it should not be delayed to serialization.
There was however a big problem with the code in transform.c, it was not
applying the stylesheet cascade heritance for output informations. I had to
cleanup both parts, patch enclosed,

    thanks for the report, a few existing testcase results were wrong!

Daniel

-- 
Daniel Veillard      | Red Hat Network http://redhat.com/products/network/
veillard@redhat.com  | libxml Gnome XML XSLT toolkit  http://xmlsoft.org/
http://veillard.com/ | Rpmfind RPM search engine http://rpmfind.net/
*** libxslt/transform.c	2001/05/07 20:55:45	1.92
--- libxslt/transform.c	2001/05/08 14:13:34
***************
*** 2496,2501 ****
--- 2496,2503 ----
      xmlDocPtr res = NULL;
      xsltTransformContextPtr ctxt = NULL;
      xmlNodePtr root;
+     const xmlChar *method;
+     const xmlChar *encoding;
  
      if ((style == NULL) || (doc == NULL))
  	return(NULL);
***************
*** 2503,2521 ****
      xsltRegisterExtras(ctxt);
      if (ctxt == NULL)
  	return(NULL);
!     if ((style->method != NULL) &&
! 	(!xmlStrEqual(style->method, (const xmlChar *) "xml"))) {
! 	if (xmlStrEqual(style->method, (const xmlChar *) "html")) {
  	    ctxt->type = XSLT_OUTPUT_HTML;
! 	    res = htmlNewDoc(style->doctypeSystem, style->doctypePublic);
  	    if (res == NULL)
  		goto error;
! 	} else if (xmlStrEqual(style->method, (const xmlChar *) "xhtml")) {
  	    xsltGenericError(xsltGenericErrorContext,
  	     "xsltApplyStylesheet: insupported method xhtml, using html\n",
  		             style->method);
  	    ctxt->type = XSLT_OUTPUT_HTML;
! 	    res = htmlNewDoc(style->doctypeSystem, style->doctypePublic);
  	    if (res == NULL)
  		goto error;
  	} else if (xmlStrEqual(style->method, (const xmlChar *) "text")) {
--- 2505,2529 ----
      xsltRegisterExtras(ctxt);
      if (ctxt == NULL)
  	return(NULL);
!     XSLT_GET_IMPORT_PTR(method, style, method)
!     if ((method != NULL) &&
! 	(!xmlStrEqual(method, (const xmlChar *) "xml"))) {
! 	const xmlChar *doctypePublic;
! 	const xmlChar *doctypeSystem;
! 
! 	XSLT_GET_IMPORT_PTR(doctypePublic, style, doctypePublic)
! 	XSLT_GET_IMPORT_PTR(doctypeSystem, style, doctypeSystem)
! 	if (xmlStrEqual(method, (const xmlChar *) "html")) {
  	    ctxt->type = XSLT_OUTPUT_HTML;
! 	    res = htmlNewDoc(doctypeSystem, doctypePublic);
  	    if (res == NULL)
  		goto error;
! 	} else if (xmlStrEqual(method, (const xmlChar *) "xhtml")) {
  	    xsltGenericError(xsltGenericErrorContext,
  	     "xsltApplyStylesheet: insupported method xhtml, using html\n",
  		             style->method);
  	    ctxt->type = XSLT_OUTPUT_HTML;
! 	    res = htmlNewDoc(doctypeSystem, doctypePublic);
  	    if (res == NULL)
  		goto error;
  	} else if (xmlStrEqual(style->method, (const xmlChar *) "text")) {
***************
*** 2553,2566 ****
      xsltFreeStackElemList(varsPop(ctxt));
      xsltCleanupTemplates(style);
  
  
!     if ((ctxt->type == XSLT_OUTPUT_XML) &&
! 	((style->doctypePublic != NULL) ||
! 	 (style->doctypeSystem != NULL))) {
  	root = xmlDocGetRootElement(res);
! 	if (root != NULL)
  	    res->intSubset = xmlCreateIntSubset(res, root->name,
! 		         style->doctypePublic, style->doctypeSystem);
      }
      xmlXPathFreeNodeSet(ctxt->nodeList);
      xsltFreeTransformContext(ctxt);
--- 2561,2578 ----
      xsltFreeStackElemList(varsPop(ctxt));
      xsltCleanupTemplates(style);
  
+ 
+     if (ctxt->type == XSLT_OUTPUT_XML) {
+ 	const xmlChar *doctypePublic;
+ 	const xmlChar *doctypeSystem;
  
! 	XSLT_GET_IMPORT_PTR(doctypePublic, style, doctypePublic)
! 	XSLT_GET_IMPORT_PTR(doctypeSystem, style, doctypeSystem)
  	root = xmlDocGetRootElement(res);
! 	if ((root != NULL) &&
! 	    ((doctypePublic != NULL) || (doctypeSystem != NULL)))
  	    res->intSubset = xmlCreateIntSubset(res, root->name,
! 		         doctypePublic, doctypeSystem);
      }
      xmlXPathFreeNodeSet(ctxt->nodeList);
      xsltFreeTransformContext(ctxt);
*** libxslt/xsltutils.c	2001/05/04 15:08:22	1.25
--- libxslt/xsltutils.c	2001/05/08 14:13:35
***************
*** 503,509 ****
          return(-1);
      }
  
-     /* TODO: when outputing and having imported stylesheets, apply cascade */
      base = buf->written;
  
      XSLT_GET_IMPORT_PTR(method, style, method)
--- 503,508 ----
***************
*** 545,559 ****
  	int standalone;
  	int indent;
  	const xmlChar *version;
- 	const xmlChar *doctypePublic;
- 	const xmlChar *doctypeSystem;
  
  	XSLT_GET_IMPORT_INT(omitXmlDecl, style, omitXmlDeclaration);
  	XSLT_GET_IMPORT_INT(standalone, style, standalone);
  	XSLT_GET_IMPORT_INT(indent, style, indent);
  	XSLT_GET_IMPORT_PTR(version, style, version)
- 	XSLT_GET_IMPORT_PTR(doctypePublic, style, doctypePublic)
- 	XSLT_GET_IMPORT_PTR(doctypeSystem, style, doctypeSystem)
  
  	if (omitXmlDecl != 1) {
  	    xmlOutputBufferWriteString(buf, "<?xml version=");
--- 544,554 ----
***************
*** 584,622 ****
  		    break;
  	    }
  	    xmlOutputBufferWriteString(buf, "?>\n");
- 	}
- 	if ((doctypePublic != NULL) || (doctypeSystem != NULL)) {
- 	    xmlNodePtr cur = result->children;
- 
- 	    while (cur != NULL) {
- 		if (cur->type == XML_ELEMENT_NODE)
- 		    break;
- 		cur = cur->next;
- 	    }
- 	    if ((cur != NULL) && (cur->name != NULL)) {
- 		xmlOutputBufferWriteString(buf, "<!DOCTYPE ");
- 		xmlOutputBufferWriteString(buf, (const char *) cur->name);
- 		if (doctypePublic != NULL) {
- 		    if (doctypeSystem != NULL) {
- 			xmlOutputBufferWriteString(buf, " PUBLIC ");
- 			xmlBufferWriteQuotedString(buf->buffer,
- 				         doctypePublic);
- 			xmlOutputBufferWriteString(buf, " ");
- 			xmlBufferWriteQuotedString(buf->buffer,
- 				         doctypeSystem);
- 		    } else {
- 			xmlOutputBufferWriteString(buf, " PUBLIC \"-\" ");
- 			xmlBufferWriteQuotedString(buf->buffer,
- 				         doctypeSystem);
- 		    }
- 
- 		} else {
- 		    xmlOutputBufferWriteString(buf, " SYSTEM ");
- 		    xmlBufferWriteQuotedString(buf->buffer,
- 				     doctypeSystem);
- 		}
- 		xmlOutputBufferWriteString(buf, ">\n");
- 	    }
  	}
  	if (result->children != NULL) {
  	    xmlNodePtr child = result->children;
--- 579,584 ----


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