[EDIT: Changed title to better conceptualize the question.]
The value of the attribute @xml:space can be either "default" or "preserve". XML specifies what the second means but leaves the first up to the application. (I think I have that correct.) So what if the application wants default to implement XSchema’s collapse? How could XSLT 1.0 actually do this?
I think the built-in template for processing text, that is,
<xsl:template match="text()">
<xsl:value-of select="."/>
</xsl:template>
would need to be replaced with something like this pseudo-code:
<xsl:choose>
<xsl:when test="../@xml:space='preserve'"
<xsl:value-of select="."/>
</xsl:when>
<xsl:otherwise>
if position(.)=1 then output LTRIM(value-of(.))
if position(.)=last() then output RTRIM(value-of(.))
if position(.)= 1 and last()=1 then output normalize-space(.)
</xsl:otherwise>
</xsl:choose>
This input then:
<persName> The man is
<forename>Edward</forename>
<forename>George</forename>
<surname type="linked">Bulwer-Lytton</surname>, <roleName>Baron Lytton of
<placeName>Knebworth</placeName>
</roleName>
</persName>
would get rendered correctly as The man is Edward George Bulwer-Lytton, Baron Lytton of Knebworth with the space before The man and after Knebworth trimmed and the spaces between Edward and George collapsed. (The example is from TEI.)
[EDIT: I removed an incorrect and misleading paragraph here.]
The XSLT 1.0 to implement that pseudo-code would need to be executed for every text node. Wouldn’t that be ugly and slow? [EDIT: Or maybe not. I simplified the pseudo code. Are there fast trim routines? Is the choose really that slow?]
Bottom line: How does one implement XSchema’s collapse in XSLT 1.0 (with only browser-embedded extensions)?
I hope I’m saying all that correctly. And I hope the code is simple. I haven’t yet seen how it can be. [EDIT: Changed xs:collapse to XSchema’s collapse.]
I checked at xml-dev, and it turns out I was correct about the meaning and intended use of @xml:space.
Here is code to normalize whitespace in mixed-content elements (that’s a better way to say what I wanted to do):
Filtering on
@xml:spaceallowspreserveto override. Thetest=is just a way to test for whitespace. The priorities resolve the conflict caused when a node is the only text node in an element, and thus both the first and the last.