modified the existing APIs to handle XHTML1 serialization rules

* tree.c include/libxml/tree.h: modified the existing APIs
  to handle XHTML1 serialization rules automatically, also add
  xmlIsXHTML() to libxml2 API. Some tweaking to make sure
  libxslt serialization uses it when needed without changing
  the library API.
* test/xhtml1 result/noent/xhtml1 result/valid/xhtml1.xhtml
  result/xhtml1: added a new test specifically for xhtml1 output
  and updated the result of one XHTML1 test
Daniel
This commit is contained in:
Daniel Veillard 2002-11-21 14:10:52 +00:00
parent c14401e4d1
commit d5c2f92df4
7 changed files with 681 additions and 52 deletions

View File

@ -1,3 +1,14 @@
Thu Nov 21 15:05:45 CET 2002 Daniel Veillard <daniel@veillard.com>
* tree.c include/libxml/tree.h: modified the existing APIs
to handle XHTML1 serialization rules automatically, also add
xmlIsXHTML() to libxml2 API. Some tweaking to make sure
libxslt serialization uses it when needed without changing
the library API.
* test/xhtml1 result/noent/xhtml1 result/valid/xhtml1.xhtml
result/xhtml1: added a new test specifically for xhtml1 output
and updated the result of one XHTML1 test
Wed Nov 20 14:24:56 CET 2002 Daniel Veillard <daniel@veillard.com>
* xinclude.c parserInternals.c encoding.c: fixed #99082

View File

@ -868,6 +868,12 @@ int xmlSaveFileEnc (const char *filename,
xmlDocPtr cur,
const char *encoding);
/*
* XHTML
*/
int xmlIsXHTML (const xmlChar *systemID,
const xmlChar *publicID);
/*
* Compression.
*/

30
result/noent/xhtml1 Normal file
View File

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!-- 3.1.1 3/ -->
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Virtual Library</title>
</head>
<!-- 4.8 -->
<script type="text/javascript"><![CDATA[
... unescaped script content ...
]]></script>
<body>
<p>Moved to <a href="http://example.org/">example.org</a>.</p>
</body>
<!-- C2 -->
<img src="foo.gif" alt="foo" />
<!-- C3 -->
<p></p>
<!-- C7 -->
<p lang="fr" xml:lang="fr">coucou</p>
<p xml:lang="fr" lang="fr">salut</p>
<!-- C8 -->
<p name="fragid" id="fragid">test</p>
<!-- 4.5 -->
<dl compact="compact">
<dt>Internet Engineering Task Force</dt>
<dd>An organization which establishes technical standards for the Internet</dd>
</dl>
</html>

View File

@ -2,11 +2,11 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "dtds/xhtml1-strict.dtd">
<?xml-stylesheet href="W3C-PR.css" type="text/css"?>
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>XHTML 1.0: The Extensible HyperText Markup
Language</title>
<link rel="stylesheet" href="W3C-PR.css" type="text/css"/>
<style type="text/css">
<link rel="stylesheet" href="W3C-PR.css" type="text/css" />
<style type="text/css"><![CDATA[
span.term { font-style: italic; color: rgb(0, 0, 192) }
code {
color: green;
@ -49,14 +49,14 @@ div.contents {
}
.tocline { list-style: none; }
table.exceptions { background-color: rgb(255,255,153); }
</style>
]]></style>
</head>
<body>
<div class="navbar">
<a href="#toc">table of contents</a>
<hr/>
<hr />
</div>
<div class="head"><p><a href="http://www.w3.org/"><img class="head" src="w3c_home.gif" alt="W3C"/></a></p>
<div class="head"><p><a href="http://www.w3.org/"><img class="head" src="w3c_home.gif" alt="W3C" /></a></p>
<h1 class="head"><a name="title" id="title">XHTML</a><sup>&#x2122;</sup> 1.0:
The Extensible HyperText Markup Language</h1>
@ -69,7 +69,7 @@ The Extensible HyperText Markup Language</h1>
<dt>This version:</dt>
<dd><a href="http://www.w3.org/TR/1999/PR-xhtml1-19991210">
http://www.w3.org/TR/1999/PR-xhtml1-19991210</a> <br/>
http://www.w3.org/TR/1999/PR-xhtml1-19991210</a> <br />
(<a href="xhtml1.ps">Postscript version</a>,
<a href="xhtml1.pdf">PDF version</a>,
<a href="xhtml1.zip">ZIP archive</a>, or
@ -100,7 +100,7 @@ liability</a>, <a href="http://www.w3.org/Consortium/Legal/ipr-notice#W3C_Tradem
trademark</a>, <a href="http://www.w3.org/Consortium/Legal/copyright-documents">document
use</a> and <a href="http://www.w3.org/Consortium/Legal/copyright-software">software
licensing</a> rules apply.</p>
<hr/>
<hr />
</div>
<h2 class="notoc">Abstract</h2>
@ -1047,7 +1047,7 @@ standard HTML elements plus a group of elements geared to the
specialist's needs.</p>
<!--OddPage-->
<h1><a name="appendices" id="appendices"/>
<h1><a name="appendices" id="appendices"></a>
<a name="dtds" id="dtds">Appendix A. DTDs</a></h1>
<p><b>This appendix is normative.</b></p>
@ -1328,29 +1328,29 @@ Acknowledgements</a></h1>
members of the W3C HTML working group:</p>
<dl>
<dd>Steven Pemberton, CWI (HTML Working Group Chair)<br/>
Murray Altheim, Sun Microsystems<br/>
Daniel Austin, CNET: The Computer Network<br/>
Frank Boumphrey, HTML Writers Guild<br/>
John Burger, Mitre<br/>
Andrew W. Donoho, IBM<br/>
Sam Dooley, IBM<br/>
Klaus Hofrichter, GMD<br/>
Philipp Hoschka, W3C<br/>
Masayasu Ishikawa, W3C<br/>
Warner ten Kate, Philips Electronics<br/>
Peter King, Phone.com<br/>
Paula Klante, JetForm<br/>
Shin'ichi Matsui, W3C/Panasonic<br/>
<dd>Steven Pemberton, CWI (HTML Working Group Chair)<br />
Murray Altheim, Sun Microsystems<br />
Daniel Austin, CNET: The Computer Network<br />
Frank Boumphrey, HTML Writers Guild<br />
John Burger, Mitre<br />
Andrew W. Donoho, IBM<br />
Sam Dooley, IBM<br />
Klaus Hofrichter, GMD<br />
Philipp Hoschka, W3C<br />
Masayasu Ishikawa, W3C<br />
Warner ten Kate, Philips Electronics<br />
Peter King, Phone.com<br />
Paula Klante, JetForm<br />
Shin'ichi Matsui, W3C/Panasonic<br />
Shane McCarron, Applied Testing and Technology (The Open Group through August
1999)<br/>
Ann Navarro, HTML Writers Guild<br/>
Zach Nies, Quark<br/>
Dave Raggett, W3C/HP (W3C lead for HTML)<br/>
Patrick Schmitz, Microsoft<br/>
Sebastian Schnitzenbaumer, Stack Overflow<br/>
Chris Wilson, Microsoft<br/>
Ted Wugofski, Gateway 2000<br/>
1999)<br />
Ann Navarro, HTML Writers Guild<br />
Zach Nies, Quark<br />
Dave Raggett, W3C/HP (W3C lead for HTML)<br />
Patrick Schmitz, Microsoft<br />
Sebastian Schnitzenbaumer, Stack Overflow<br />
Chris Wilson, Microsoft<br />
Ted Wugofski, Gateway 2000<br />
Dan Zigmond, WebTV Networks</dd>
</dl>
@ -1364,21 +1364,21 @@ Dan Zigmond, WebTV Networks</dd>
<dt><a name="ref-css2" id="ref-css2"><b>[CSS2]</b></a></dt>
<dd><a href="http://www.w3.org/TR/REC-CSS2">&quot;Cascading Style Sheets, level 2 (CSS2) Specification&quot;</a>, B.
Bos, H. W. Lie, C. Lilley, I. Jacobs, 12 May 1998.<br/>
Bos, H. W. Lie, C. Lilley, I. Jacobs, 12 May 1998.<br />
Available at: <a href="http://www.w3.org/TR/REC-CSS2">
http://www.w3.org/TR/REC-CSS2</a></dd>
<dt><a name="ref-dom" id="ref-dom"><b>[DOM]</b></a></dt>
<dd><a href="http://www.w3.org/TR/REC-DOM-Level-1">&quot;Document Object Model (DOM) Level 1 Specification&quot;</a>, Lauren
Wood <i>et al.</i>, 1 October 1998.<br/>
Wood <i>et al.</i>, 1 October 1998.<br />
Available at: <a href="http://www.w3.org/TR/REC-DOM-Level-1">
http://www.w3.org/TR/REC-DOM-Level-1</a></dd>
<dt><a name="ref-html4" id="ref-html4"><b>[HTML]</b></a></dt>
<dd><a href="http://www.w3.org/TR/1999/PR-html40-19990824">&quot;HTML 4.01 Specification&quot;</a>, D. Raggett, A. Le&#xA0;Hors, I.
Jacobs, 24 August 1999.<br/>
Jacobs, 24 August 1999.<br />
Available at: <a href="http://www.w3.org/TR/1999/PR-html40-19990824">
http://www.w3.org/TR/1999/PR-html40-19990824</a></dd>
@ -1394,7 +1394,7 @@ and Electronics Engineers, Inc, 1990.</dd>
<dd><a href="http://www.ietf.org/rfc/rfc2046.txt">&quot;RFC2046: Multipurpose Internet Mail Extensions (MIME) Part
Two: Media Types&quot;</a>, N. Freed and N. Borenstein, November
1996.<br/>
1996.<br />
Available at <a href="http://www.ietf.org/rfc/rfc2046.txt">
http://www.ietf.org/rfc/rfc2046.txt</a>. Note that this RFC
obsoletes RFC1521, RFC1522, and RFC1590.</dd>
@ -1403,7 +1403,7 @@ obsoletes RFC1521, RFC1522, and RFC1590.</dd>
[RFC2119]</b></a></dt>
<dd><a href="http://www.ietf.org/rfc/rfc2119.txt">&quot;RFC2119: Key words for use in RFCs to Indicate Requirement
Levels&quot;</a>, S. Bradner, March 1997.<br/>
Levels&quot;</a>, S. Bradner, March 1997.<br />
Available at: <a href="http://www.ietf.org/rfc/rfc2119.txt">
http://www.ietf.org/rfc/rfc2119.txt</a></dd>
@ -1411,7 +1411,7 @@ http://www.ietf.org/rfc/rfc2119.txt</a></dd>
[RFC2376]</b></a></dt>
<dd><a href="http://www.ietf.org/rfc/rfc2376.txt">&quot;RFC2376: XML Media Types&quot;</a>, E. Whitehead, M. Murata, July
1998.<br/>
1998.<br />
Available at: <a href="http://www.ietf.org/rfc/rfc2376.txt">
http://www.ietf.org/rfc/rfc2376.txt</a></dd>
@ -1420,33 +1420,33 @@ http://www.ietf.org/rfc/rfc2376.txt</a></dd>
<dd><a href="http://www.ietf.org/rfc/rfc2396.txt">&quot;RFC2396: Uniform Resource Identifiers (URI): Generic
Syntax&quot;</a>, T. Berners-Lee, R. Fielding, L. Masinter, August
1998.<br/>
This document updates RFC1738 and RFC1808.<br/>
1998.<br />
This document updates RFC1738 and RFC1808.<br />
Available at: <a href="http://www.ietf.org/rfc/rfc2396.txt">
http://www.ietf.org/rfc/rfc2396.txt</a></dd>
<dt><a name="ref-xml" id="ref-xml"><b>[XML]</b></a></dt>
<dd><a href="http://www.w3.org/TR/REC-xml">&quot;Extensible Markup Language (XML) 1.0 Specification&quot;</a>, T.
Bray, J. Paoli, C. M. Sperberg-McQueen, 10 February 1998.<br/>
Bray, J. Paoli, C. M. Sperberg-McQueen, 10 February 1998.<br />
Available at: <a href="http://www.w3.org/TR/REC-xml">
http://www.w3.org/TR/REC-xml</a></dd>
<dt><a name="ref-xmlns" id="ref-xmlns"><b>[XMLNAMES]</b></a></dt>
<dd><a href="http://www.w3.org/TR/REC-xml-names">&quot;Namespaces in XML&quot;</a>, T. Bray, D. Hollander, A. Layman, 14
January 1999.<br/>
January 1999.<br />
XML namespaces provide a simple method for qualifying names used
in XML documents by associating them with namespaces identified
by URI.<br/>
by URI.<br />
Available at: <a href="http://www.w3.org/TR/REC-xml-names">
http://www.w3.org/TR/REC-xml-names</a></dd>
</dl>
<p><a href="http://www.w3.org/WAI/WCAG1AAA-Conformance" title="Explanation of Level Triple-A Conformance">
<img height="32" width="88" src="wcag1AAA.gif" alt="Level Triple-A conformance icon, W3C-WAI Web Content Accessibility Guidelines 1.0"/></a></p>
<img height="32" width="88" src="wcag1AAA.gif" alt="Level Triple-A conformance icon, W3C-WAI Web Content Accessibility Guidelines 1.0" /></a></p>
<div class="navbar">
<hr/>
<hr />
<a href="#toc">table of contents</a>
</div>
</body>

30
result/xhtml1 Normal file
View File

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!-- 3.1.1 3/ -->
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Virtual Library</title>
</head>
<!-- 4.8 -->
<script type="text/javascript"><![CDATA[
... unescaped script content ...
]]></script>
<body>
<p>Moved to <a href="http://example.org/">example.org</a>.</p>
</body>
<!-- C2 -->
<img src="foo.gif" alt="foo" />
<!-- C3 -->
<p></p>
<!-- C7 -->
<p lang="fr" xml:lang="fr">coucou</p>
<p xml:lang="fr" lang="fr">salut</p>
<!-- C8 -->
<p name="fragid" id="fragid">test</p>
<!-- 4.5 -->
<dl compact="compact">
<dt>Internet Engineering Task Force</dt>
<dd>An organization which establishes technical standards for the Internet</dd>
</dl>
</html>

34
test/xhtml1 Normal file
View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!-- 3.1.1 3/ -->
<html xml:lang="en" lang="en">
<head>
<title>Virtual Library</title>
</head>
<!-- 4.8 -->
<script type="text/javascript">
... unescaped script content ...
</script>
<body>
<p>Moved to <a href="http://example.org/">example.org</a>.</p>
</body>
<!-- C2 -->
<img src="foo.gif" alt="foo"/>
<!-- C3 -->
<p/>
<!-- C7 -->
<p lang="fr">coucou</p>
<p xml:lang="fr">salut</p>
<!-- C8 -->
<p name="fragid">test</p>
<!-- 4.5 -->
<dl compact="">
<dt>Internet Engineering Task Force</dt>
<dd>An organization which establishes technical standards for the Internet</dd>
</dl>
</html>

534
tree.c
View File

@ -1,6 +1,9 @@
/*
* tree.c : implementation of access function for an XML tree.
*
* References:
* XHTML 1.0 W3C REC: http://www.w3.org/TR/2002/REC-xhtml1-20020801/
*
* See Copyright for the status of this software.
*
* daniel@veillard.com
@ -31,6 +34,9 @@
#include <libxml/xmlerror.h>
#include <libxml/parserInternals.h>
#include <libxml/globals.h>
#ifdef LIBXML_HTML_ENABLED
#include <libxml/HTMLtree.h>
#endif
xmlNsPtr xmlNewReconciliedNs(xmlDocPtr doc, xmlNodePtr tree, xmlNsPtr ns);
@ -5950,8 +5956,6 @@ xmlBufferWriteQuotedString(xmlBufferPtr buf, const xmlChar *string) {
static void
xmlNodeListDump(xmlBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur, int level,
int format);
void
htmlNodeDump(xmlBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur);
/**
* xmlNsDump:
@ -6486,8 +6490,15 @@ xmlElemDump(FILE *f, xmlDocPtr doc, xmlNodePtr cur) {
************************************************************************/
static void
xhtmlNodeDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur,
int level, int format, const char *encoding);
static void
xmlNodeListDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur,
int level, int format, const char *encoding);
static void
xmlNodeDumpOutputInternal(xmlOutputBufferPtr buf, xmlDocPtr doc,
xmlNodePtr cur, int level, int format, const char *encoding);
/**
* xmlNsDumpOutput:
* @buf: the XML buffer output
@ -6661,7 +6672,7 @@ xmlNodeListDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
(cur->type == XML_ELEMENT_NODE))
for (i = 0;i < level;i++)
xmlOutputBufferWriteString(buf, xmlTreeIndentString);
xmlNodeDumpOutput(buf, doc, cur, level, format, encoding);
xmlNodeDumpOutputInternal(buf, doc, cur, level, format, encoding);
if (format) {
xmlOutputBufferWriteString(buf, "\n");
}
@ -6670,7 +6681,7 @@ xmlNodeListDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
}
/**
* xmlNodeDumpOutput:
* xmlNodeDumpOutputInternal:
* @buf: the XML buffer output
* @doc: the document
* @cur: the current node
@ -6682,9 +6693,9 @@ xmlNodeListDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
* Note that format = 1 provide node indenting only if xmlIndentTreeOutput = 1
* or xmlKeepBlanksDefault(0) was called
*/
void
xmlNodeDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur,
int level, int format, const char *encoding) {
static void
xmlNodeDumpOutputInternal(xmlOutputBufferPtr buf, xmlDocPtr doc,
xmlNodePtr cur, int level, int format, const char *encoding) {
int i;
xmlNodePtr tmp;
@ -6836,6 +6847,47 @@ xmlNodeDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur,
xmlOutputBufferWriteString(buf, ">");
}
/**
* xmlNodeDumpOutput:
* @buf: the XML buffer output
* @doc: the document
* @cur: the current node
* @level: the imbrication level for indenting
* @format: is formatting allowed
* @encoding: an optional encoding string
*
* Dump an XML node, recursive behaviour, children are printed too.
* Note that format = 1 provide node indenting only if xmlIndentTreeOutput = 1
* or xmlKeepBlanksDefault(0) was called
*/
void
xmlNodeDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur,
int level, int format, const char *encoding) {
#ifdef LIBXML_HTML_ENABLED
xmlDtdPtr dtd;
int is_xhtml = 0;
dtd = xmlGetIntSubset(doc);
if (dtd != NULL) {
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(cur, (const xmlChar *) encoding);
else
htmlSetMetaEncoding(cur, BAD_CAST "UTF-8");
}
}
if (is_xhtml)
xhtmlNodeDumpOutput(buf, doc, cur, level, format, encoding);
else
#endif
xmlNodeDumpOutputInternal(buf, doc, cur, level, format, encoding);
}
/**
* xmlDocContentDumpOutput:
* @buf: the XML buffer output
@ -6850,6 +6902,11 @@ xmlNodeDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur,
static void
xmlDocContentDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr cur,
const char *encoding, int format) {
#ifdef LIBXML_HTML_ENABLED
xmlDtdPtr dtd;
int is_xhtml = 0;
#endif
xmlOutputBufferWriteString(buf, "<?xml version=");
if (cur->version != NULL)
xmlBufferWriteQuotedString(buf->buffer, cur->version);
@ -6874,17 +6931,478 @@ xmlDocContentDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr cur,
break;
}
xmlOutputBufferWriteString(buf, "?>\n");
#ifdef LIBXML_HTML_ENABLED
dtd = xmlGetIntSubset(cur);
if (dtd != NULL) {
is_xhtml = xmlIsXHTML(dtd->SystemID, dtd->ExternalID);
if (is_xhtml < 0) is_xhtml = 0;
}
if (is_xhtml) {
if (encoding != NULL)
htmlSetMetaEncoding(cur, (const xmlChar *) encoding);
else
htmlSetMetaEncoding(cur, BAD_CAST "UTF-8");
}
#endif
if (cur->children != NULL) {
xmlNodePtr child = cur->children;
while (child != NULL) {
xmlNodeDumpOutput(buf, cur, child, 0, format, encoding);
#ifdef LIBXML_HTML_ENABLED
if (is_xhtml)
xhtmlNodeDumpOutput(buf, cur, child, 0, format, encoding);
else
#endif
xmlNodeDumpOutputInternal(buf, cur, child, 0, format, encoding);
xmlOutputBufferWriteString(buf, "\n");
child = child->next;
}
}
}
#ifdef LIBXML_HTML_ENABLED
/************************************************************************
* *
* Functions specific to XHTML serialization *
* *
************************************************************************/
#define XHTML_STRICT_PUBLIC_ID BAD_CAST \
"-//W3C//DTD XHTML 1.0 Strict//EN"
#define XHTML_STRICT_SYSTEM_ID BAD_CAST \
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
#define XHTML_FRAME_PUBLIC_ID BAD_CAST \
"-//W3C//DTD XHTML 1.0 Frameset//EN"
#define XHTML_FRAME_SYSTEM_ID BAD_CAST \
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd"
#define XHTML_TRANS_PUBLIC_ID BAD_CAST \
"-//W3C//DTD XHTML 1.0 Transitional//EN"
#define XHTML_TRANS_SYSTEM_ID BAD_CAST \
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
#define XHTML_NS_NAME BAD_CAST "http://www.w3.org/1999/xhtml"
/**
* xmlIsXHTML:
* @systemID: the system identifier
* @publicID: the public identifier
*
* Try to find if the document correspond to an XHTML DTD
*
* Returns 1 if true, 0 if not and -1 in case of error
*/
int
xmlIsXHTML(const xmlChar *systemID, const xmlChar *publicID) {
if ((systemID == NULL) && (publicID == NULL))
return(-1);
if (publicID != NULL) {
if (xmlStrEqual(publicID, XHTML_STRICT_PUBLIC_ID)) return(1);
if (xmlStrEqual(publicID, XHTML_FRAME_PUBLIC_ID)) return(1);
if (xmlStrEqual(publicID, XHTML_TRANS_PUBLIC_ID)) return(1);
}
if (systemID != NULL) {
if (xmlStrEqual(systemID, XHTML_STRICT_SYSTEM_ID)) return(1);
if (xmlStrEqual(systemID, XHTML_FRAME_SYSTEM_ID)) return(1);
if (xmlStrEqual(systemID, XHTML_TRANS_SYSTEM_ID)) return(1);
}
return(0);
}
/**
* xhtmlIsEmpty:
* @node: the node
*
* Check if a node is an empty xhtml node
*
* Returns 1 if the node is an empty node, 0 if not and -1 in case of error
*/
static int
xhtmlIsEmpty(xmlNodePtr node) {
if (node == NULL)
return(-1);
if (node->type != XML_ELEMENT_NODE)
return(0);
if ((node->ns != NULL) && (!xmlStrEqual(node->ns->href, XHTML_NS_NAME)))
return(0);
if (node->children != NULL)
return(0);
switch (node->name[0]) {
case 'a':
if (xmlStrEqual(node->name, BAD_CAST "area"))
return(1);
return(0);
case 'b':
if (xmlStrEqual(node->name, BAD_CAST "br"))
return(1);
if (xmlStrEqual(node->name, BAD_CAST "base"))
return(1);
if (xmlStrEqual(node->name, BAD_CAST "basefont"))
return(1);
return(0);
case 'c':
if (xmlStrEqual(node->name, BAD_CAST "col"))
return(1);
return(0);
case 'f':
if (xmlStrEqual(node->name, BAD_CAST "frame"))
return(1);
return(0);
case 'h':
if (xmlStrEqual(node->name, BAD_CAST "hr"))
return(1);
return(0);
case 'i':
if (xmlStrEqual(node->name, BAD_CAST "img"))
return(1);
if (xmlStrEqual(node->name, BAD_CAST "input"))
return(1);
if (xmlStrEqual(node->name, BAD_CAST "isindex"))
return(1);
return(0);
case 'l':
if (xmlStrEqual(node->name, BAD_CAST "link"))
return(1);
return(0);
case 'm':
if (xmlStrEqual(node->name, BAD_CAST "meta"))
return(1);
return(0);
case 'p':
if (xmlStrEqual(node->name, BAD_CAST "param"))
return(1);
return(0);
}
return(0);
}
/**
* xhtmlAttrListDumpOutput:
* @buf: the XML buffer output
* @doc: the document
* @cur: the first attribute pointer
* @encoding: an optional encoding string
*
* Dump a list of XML attributes
*/
static void
xhtmlAttrListDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
xmlAttrPtr cur, const char *encoding) {
xmlAttrPtr xml_lang = NULL;
xmlAttrPtr lang = NULL;
xmlAttrPtr name = NULL;
xmlAttrPtr id = NULL;
if (cur == NULL) {
#ifdef DEBUG_TREE
xmlGenericError(xmlGenericErrorContext,
"xmlAttrListDumpOutput : property == NULL\n");
#endif
return;
}
while (cur != NULL) {
if ((cur->ns == NULL) && (xmlStrEqual(cur->name, BAD_CAST "id")))
id = cur;
else
if ((cur->ns == NULL) && (xmlStrEqual(cur->name, BAD_CAST "name")))
name = cur;
else
if ((cur->ns == NULL) && (xmlStrEqual(cur->name, BAD_CAST "lang")))
lang = cur;
else
if ((cur->ns != NULL) && (xmlStrEqual(cur->name, BAD_CAST "lang")) &&
(xmlStrEqual(cur->ns->prefix, BAD_CAST "xml")))
xml_lang = cur;
else if ((cur->ns == NULL) &&
((cur->children == NULL) ||
(cur->children->content == NULL) ||
(cur->children->content[0] == 0)) &&
(htmlIsBooleanAttr(cur->name))) {
if (cur->children != NULL)
xmlFreeNode(cur->children);
cur->children = xmlNewText(cur->name);
if (cur->children != NULL)
cur->children->parent = (xmlNodePtr) cur;
}
xmlAttrDumpOutput(buf, doc, cur, encoding);
cur = cur->next;
}
/*
* C.8
*/
if ((name != NULL) && (id == NULL)) {
xmlOutputBufferWriteString(buf, " id=\"");
xmlAttrSerializeContent(buf->buffer, doc, name);
xmlOutputBufferWriteString(buf, "\"");
}
/*
* C.7.
*/
if ((lang != NULL) && (xml_lang == NULL)) {
xmlOutputBufferWriteString(buf, " xml:lang=\"");
xmlAttrSerializeContent(buf->buffer, doc, lang);
xmlOutputBufferWriteString(buf, "\"");
} else
if ((xml_lang != NULL) && (lang == NULL)) {
xmlOutputBufferWriteString(buf, " lang=\"");
xmlAttrSerializeContent(buf->buffer, doc, xml_lang);
xmlOutputBufferWriteString(buf, "\"");
}
}
/**
* xhtmlNodeListDumpOutput:
* @buf: the XML buffer output
* @doc: the XHTML document
* @cur: the first node
* @level: the imbrication level for indenting
* @format: is formatting allowed
* @encoding: an optional encoding string
*
* Dump an XML node list, recursive behaviour, children are printed too.
* Note that format = 1 provide node indenting only if xmlIndentTreeOutput = 1
* or xmlKeepBlanksDefault(0) was called
*/
static void
xhtmlNodeListDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
xmlNodePtr cur, int level, int format, const char *encoding) {
int i;
if (cur == NULL) {
#ifdef DEBUG_TREE
xmlGenericError(xmlGenericErrorContext,
"xhtmlNodeListDumpOutput : node == NULL\n");
#endif
return;
}
while (cur != NULL) {
if ((format) && (xmlIndentTreeOutput) &&
(cur->type == XML_ELEMENT_NODE))
for (i = 0;i < level;i++)
xmlOutputBufferWriteString(buf, xmlTreeIndentString);
xhtmlNodeDumpOutput(buf, doc, cur, level, format, encoding);
if (format) {
xmlOutputBufferWriteString(buf, "\n");
}
cur = cur->next;
}
}
/**
* xhtmlNodeDumpOutput:
* @buf: the XML buffer output
* @doc: the XHTML document
* @cur: the current node
* @level: the imbrication level for indenting
* @format: is formatting allowed
* @encoding: an optional encoding string
*
* Dump an XHTML node, recursive behaviour, children are printed too.
* Note that format = 1 provide node indenting only if xmlIndentTreeOutput = 1
* or xmlKeepBlanksDefault(0) was called
*/
static void
xhtmlNodeDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur,
int level, int format, const char *encoding) {
int i;
xmlNodePtr tmp;
if (cur == NULL) {
#ifdef DEBUG_TREE
xmlGenericError(xmlGenericErrorContext,
"xmlNodeDumpOutput : node == NULL\n");
#endif
return;
}
if (cur->type == XML_XINCLUDE_START)
return;
if (cur->type == XML_XINCLUDE_END)
return;
if (cur->type == XML_DTD_NODE) {
xmlDtdDumpOutput(buf, (xmlDtdPtr) cur, encoding);
return;
}
if (cur->type == XML_ELEMENT_DECL) {
xmlDumpElementDecl(buf->buffer, (xmlElementPtr) cur);
return;
}
if (cur->type == XML_ATTRIBUTE_DECL) {
xmlDumpAttributeDecl(buf->buffer, (xmlAttributePtr) cur);
return;
}
if (cur->type == XML_ENTITY_DECL) {
xmlDumpEntityDecl(buf->buffer, (xmlEntityPtr) cur);
return;
}
if (cur->type == XML_TEXT_NODE) {
if (cur->content != NULL) {
if ((cur->name == xmlStringText) ||
(cur->name != xmlStringTextNoenc)) {
xmlChar *buffer;
if (encoding == NULL)
buffer = xmlEncodeEntitiesReentrant(doc, cur->content);
else
buffer = xmlEncodeSpecialChars(doc, cur->content);
if (buffer != NULL) {
xmlOutputBufferWriteString(buf, (const char *)buffer);
xmlFree(buffer);
}
} else {
/*
* Disable escaping, needed for XSLT
*/
xmlOutputBufferWriteString(buf, (const char *) cur->content);
}
}
return;
}
if (cur->type == XML_PI_NODE) {
if (cur->content != NULL) {
xmlOutputBufferWriteString(buf, "<?");
xmlOutputBufferWriteString(buf, (const char *)cur->name);
if (cur->content != NULL) {
xmlOutputBufferWriteString(buf, " ");
xmlOutputBufferWriteString(buf, (const char *)cur->content);
}
xmlOutputBufferWriteString(buf, "?>");
} else {
xmlOutputBufferWriteString(buf, "<?");
xmlOutputBufferWriteString(buf, (const char *)cur->name);
xmlOutputBufferWriteString(buf, "?>");
}
return;
}
if (cur->type == XML_COMMENT_NODE) {
if (cur->content != NULL) {
xmlOutputBufferWriteString(buf, "<!--");
xmlOutputBufferWriteString(buf, (const char *)cur->content);
xmlOutputBufferWriteString(buf, "-->");
}
return;
}
if (cur->type == XML_ENTITY_REF_NODE) {
xmlOutputBufferWriteString(buf, "&");
xmlOutputBufferWriteString(buf, (const char *)cur->name);
xmlOutputBufferWriteString(buf, ";");
return;
}
if (cur->type == XML_CDATA_SECTION_NODE) {
xmlOutputBufferWriteString(buf, "<![CDATA[");
if (cur->content != NULL)
xmlOutputBufferWriteString(buf, (const char *)cur->content);
xmlOutputBufferWriteString(buf, "]]>");
return;
}
if (format == 1) {
tmp = cur->children;
while (tmp != NULL) {
if ((tmp->type == XML_TEXT_NODE) ||
(tmp->type == XML_ENTITY_REF_NODE)) {
format = 0;
break;
}
tmp = tmp->next;
}
}
xmlOutputBufferWriteString(buf, "<");
if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
xmlOutputBufferWriteString(buf, ":");
}
xmlOutputBufferWriteString(buf, (const char *)cur->name);
if (cur->nsDef)
xmlNsListDumpOutput(buf, cur->nsDef);
if ((xmlStrEqual(cur->name, BAD_CAST "html") &&
(cur->ns == NULL) && (cur->nsDef == NULL))) {
/*
* 3.1.1. Strictly Conforming Documents A.3.1.1 3/
*/
xmlOutputBufferWriteString(buf,
" xmlns=\"http://www.w3.org/1999/xhtml\"");
}
if (cur->properties != NULL)
xhtmlAttrListDumpOutput(buf, doc, cur->properties, encoding);
if ((cur->type == XML_ELEMENT_NODE) && (cur->children == NULL)) {
if (((cur->ns == NULL) || (cur->ns->prefix == NULL)) &&
(xhtmlIsEmpty(cur) == 1)) {
/*
* C.2. Empty Elements
*/
xmlOutputBufferWriteString(buf, " />");
} else {
/*
* C.3. Element Minimization and Empty Element Content
*/
xmlOutputBufferWriteString(buf, "></");
if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
xmlOutputBufferWriteString(buf, ":");
}
xmlOutputBufferWriteString(buf, (const char *)cur->name);
xmlOutputBufferWriteString(buf, ">");
}
return;
}
xmlOutputBufferWriteString(buf, ">");
if ((cur->type != XML_ELEMENT_NODE) && (cur->content != NULL)) {
xmlChar *buffer;
if (encoding == NULL)
buffer = xmlEncodeEntitiesReentrant(doc, cur->content);
else
buffer = xmlEncodeSpecialChars(doc, cur->content);
if (buffer != NULL) {
xmlOutputBufferWriteString(buf, (const char *)buffer);
xmlFree(buffer);
}
}
/*
* 4.8. Script and Style elements
*/
if ((cur->type == XML_ELEMENT_NODE) &&
((xmlStrEqual(cur->name, BAD_CAST "script")) ||
(xmlStrEqual(cur->name, BAD_CAST "style"))) &&
((cur->ns == NULL) ||
(xmlStrEqual(cur->ns->href, XHTML_NS_NAME)))) {
xmlNodePtr child = cur->children;
while (child != NULL) {
if ((child->type == XML_TEXT_NODE) ||
(child->type == XML_CDATA_SECTION_NODE)) {
xmlOutputBufferWriteString(buf, "<![CDATA[");
if (child->content != NULL)
xmlOutputBufferWriteString(buf,
(const char *)child->content);
xmlOutputBufferWriteString(buf, "]]>");
} else {
xhtmlNodeDumpOutput(buf, doc, child, 0, 0, encoding);
}
child = child->next;
}
} else if (cur->children != NULL) {
if (format) xmlOutputBufferWriteString(buf, "\n");
xhtmlNodeListDumpOutput(buf, doc, cur->children,
(level >= 0?level+1:-1), format, encoding);
if ((xmlIndentTreeOutput) && (format))
for (i = 0;i < level;i++)
xmlOutputBufferWriteString(buf, xmlTreeIndentString);
}
xmlOutputBufferWriteString(buf, "</");
if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
xmlOutputBufferWriteString(buf, ":");
}
xmlOutputBufferWriteString(buf, (const char *)cur->name);
xmlOutputBufferWriteString(buf, ">");
}
#endif
/************************************************************************
* *
* Saving functions front-ends *