public function xhtml($markup = null)
{
// XXX: This is a minor reworking of the original xml() method.
// This should be refactored, probably.
// See http://github.com/technosophos/querypath/issues#issue/10
$omit_xml_decl = $this->options['omit_xml_declaration'];
if ($markup === true) {
// Basically, we handle the special case where we don't
// want the XML declaration to be displayed.
$omit_xml_decl = true;
} elseif (isset($markup)) {
return $this->xml($markup);
}
$length = $this->size();
if ($length == 0) {
return;
}
// Only return the first item -- that's what JQ does.
$first = $this->getFirstMatch();
// Catch cases where first item is not a legit DOM object.
if (!$first instanceof \DOMNode) {
return;
}
if ($first instanceof \DOMDocument || $first->isSameNode($first->ownerDocument->documentElement)) {
// Has the unfortunate side-effect of stripping doctype.
//$text = ($omit_xml_decl ? $this->document->saveXML($first->ownerDocument->documentElement, LIBXML_NOEMPTYTAG) : $this->document->saveXML(NULL, LIBXML_NOEMPTYTAG));
$text = $this->document->saveXML(null, LIBXML_NOEMPTYTAG);
} else {
$text = $this->document->saveXML($first, LIBXML_NOEMPTYTAG);
}
// Issue #47: Using the old trick for removing the XML tag also removed the
// doctype. So we remove it with a regex:
if ($omit_xml_decl) {
$text = preg_replace('/<\\?xml\\s[^>]*\\?>/', '', $text);
}
// This is slightly lenient: It allows for cases where code incorrectly places content
// inside of these supposedly unary elements.
$unary = '/<(area|base|basefont|br|col|frame|hr|img|input|isindex|link|meta|param)(?(?=\\s)([^>\\/]+))><\\/[^>]*>/i';
$text = preg_replace($unary, '<\\1\\2 />', $text);
// Experimental: Support for enclosing CDATA sections with comments to be both XML compat
// and HTML 4/5 compat
$cdata = '/(<!\\[CDATA\\[|\\]\\]>)/i';
$replace = $this->options['escape_xhtml_js_css_sections'];
$text = preg_replace($cdata, $replace, $text);
return $text;
}