Project

Profile

Help

Support #4396

Empty element tags not compatible with result-document ixsl methods

Added by David Priest 10 months ago. Updated 9 months ago.

Status:
Closed
Priority:
Low
Assignee:
Category:
-
Sprint/Milestone:
-
Start date:
2019-11-26
Due date:
% Done:

0%

Estimated time:
Legacy ID:
Applies to branch:
Fix Committed on Branch:
Fixed in Maintenance Release:

Description

Using ixsl:replace-content or ixsl:append-content does not work with short-form empty element tags, i.e. <div id="shortformEmptyDiv"/>. I would be surprised if this is not already known, but here is an example:

index.html

<!DOCTYPE html>
<html
	xmlns="http://www.w3.org/1999/xhtml">
	<head>
		<title>Bug Demo</title>
		<script src="js/Saxon-JS-1.2.0/SaxonJS.min.js"></script>
		<script type="text/javascript">
			window.onload = function() { 
				SaxonJS.transform({ 
					stylesheetLocation: "bug.sef.xml", 
					initialTemplate: "Q{http://www.w3.org/1999/XSL/Transform}initial-template", 
					}); 
				}
		</script>
	</head>
	<body>
		<div id="longformEmptyDiv"></div>
		<div>Here is some placeholder content.</div>
		<div id="shortformEmptyDiv"/>
		<div>Here is some placeholder content.</div>
		<div id="disappearingAct"></div>
		<div>Here is some placeholder content.</div>
	</body>
</html>

bug.xsl

<xsl:transform
	expand-text="yes"
	extension-element-prefixes="ixsl"
	version="3.0"
	xmlns="http://www.w3.org/1999/xhtml"
	xmlns:ixsl="http://saxonica.com/ns/interactiveXSLT"
	xmlns:js="http://saxonica.com/ns/globalJS"
	xmlns:xhtml="http://www.w3.org/1999/xhtml"
	xmlns:xs="http://www.w3.org/2001/XMLSchema"
	xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

	<xsl:template
		name="xsl:initial-template">
		<xsl:apply-templates select="ixsl:page()" />
	</xsl:template>

	<xsl:template
		match="div[@id='shortformEmptyDiv']">
		<xsl:message>Matched shortformEmptyDiv</xsl:message>
		<xsl:result-document href="?." method="ixsl:replace-content">
			<p>Here is some shortformEmptyDiv content.</p>
		</xsl:result-document>
	</xsl:template>

	<xsl:template
		match="div[@id='longformEmptyDiv']">
		<xsl:message>Matched longformEmptyDiv</xsl:message>
		<xsl:result-document href="?." method="ixsl:replace-content">
			<p>Here is some longformEmptyDiv content.</p>
		</xsl:result-document>
	</xsl:template>

	<xsl:template
		match="div[@id='disappearingAct']">
		<xsl:message>Matched disappearingAct</xsl:message>
		<xsl:result-document href="?." method="ixsl:replace-content">
			<p>Here is some disappearingAct content.</p>
		</xsl:result-document>
	</xsl:template>
</xsl:transform>

browser result:

<html
	xmlns="http://www.w3.org/1999/xhtml">
	<head>
		<title>Bug Demo</title>
		<script src="js/Saxon-JS-1.2.0/SaxonJS.min.js"></script>
		<script type="text/javascript">
			window.onload = function() { 
				SaxonJS.transform({ 
					stylesheetLocation: "xsl/bug.sef.xml", 
					initialTemplate: "Q{http://www.w3.org/1999/XSL/Transform}initial-template", 
					}); 
				}
		</script>
	</head>
	<body>
		<div id="longformEmptyDiv">
			<p>Here is some longformEmptyDiv content.</p>
		</div>
		<div>Here is some placeholder content.</div>
		<div id="shortformEmptyDiv">
			<p>Here is some shortformEmptyDiv content.</p>
		</div>
	</body>
</html>

You will note that the match on longformEmptyDiv correctly inserted the replacement content as a child of the div itself. However, on shortformEmptyDiv the content has replaced everything following the short form div, instead of being inserted into the div. (Consequently, the disappearingAct div goes AWOL. Indeed, its match is never made: no message appears in the browser console: the short form replacement was performed before the disappearingAct template could match.)

SaxonJS 9.8, 9.9

index.html (688 Bytes) index.html David Priest, 2019-11-26 19:52
bug.xsl (1.27 KB) bug.xsl David Priest, 2019-11-26 19:52

History

#1 Updated by Michael Kay 10 months ago

Will need to look into this more carefully, but my immediate reaction is that you are assuming the data model instance that you get from putting <div id="shortformEmptyDiv"/> through an HTML5 parser is the same as you get when you put it through an XML parser, and that this is not actually the case.

#2 Updated by Michael Kay 10 months ago

Relevant discussions:

https://stackoverflow.com/questions/5455768/why-do-browsers-think-this-div-tag-isnt-immediately-ended

https://stackoverflow.com/questions/3558119/are-non-void-self-closing-tags-valid-in-html5

In particular: "On other HTML elements [such as div], the slash is an error, but error recovery will cause browsers to ignore it and treat the tag as a regular start tag. This will usually end up with a missing end tag causing subsequent elements to be children instead of siblings.

#3 Updated by David Priest 10 months ago

Thank you for researching this further! Those answers exactly identify the root cause of the issue, and places blame on my faulty assumption and the design decisions made by HTML spec writers. I consider this a closed issue.

I note the discussion in the second link delves into the history and hairy details about this issue. It's especially interesting to note that had my server been delivering XHTML, the self-closing tag may have been processed as I had expected; and that in HTML, the behaviour actually varies wildly dependent on the tag local-name and tag namespace. What fun.

#4 Updated by Michael Kay 9 months ago

  • Tracker changed from Bug to Support
  • Status changed from New to Closed
  • Assignee set to Michael Kay

Closed; not a bug, just a quirk of the HTML environment.

Please register to edit this issue

Also available in: Atom PDF